The sensor is a main structure and concept utilized by the Context component. It defines how agents observe their environment. Although it is listed as a component, it actually is implemented as a ScriptableObject
.
The planar sensor denotes a subset of the general Spatial Sensor. The receptors are oriented on a plane, making the sensor suitable for 2D scenarios and 3D scenarios which have a (virtual) ground. Using a planar sensor in such cases has advantages. Besides the better performance, the Planar Interpolation component is available for planar sensors only. Furthermore, more complex sensor configurations are possible using the Planar Shaper utility.
When talking about 3D scenarios with a ground, the ground does not have to be flat. An arbitrary terrain can be used, there are no restrictions. Here are some examples for agents that can use a planar sensor: a plumber in a jump and run game, a car in an open world or racing game, some evil friends in an epic RPG or a group of swordsmen in a strategy game. An aircraft or a spaceship, on the other hand, should use a spatial sensor instead. Although there can be exceptions: Imagine a strategy game where you command helicopters or drones. If avoidance is not that important or it is handled by other systems, a planar sensor might be feasible, too.
Figure 1: Shows a linear sensor shape at the left and a circle sensor shape at the right.
Creating a sensor asset is very easy because it is a serialized object. To create a sensor, navigate to Assets/Create/Polarith AI » Move/Sensors/AIM Planar Sensor.
Figure 2: The popup for creating sensor assets.
Once you have got your sensor asset, you can see the following information concerning the created sensor.
Property | Description |
---|---|
ReceptorCount | Indicates how many receptors are used for this sensor. |
PlanarOrientation | Internally, rotates the sensor to match the given plane. This should match the current projection mode for your applied behaviours, VectorProjection = PlaneXZ corresponds to PlanarOrientation = PlaneXZ and so forth. |
Closed | This read-only property indicates if the sensor shape is closed. A shape is closed if the last receptor is registered as the left neighbour of the first receptor and vice versa. |
Currently, there are two different base shapes which can be created using the inspector: the line shaped sensor and the circle shaped sensor.
Property | Description |
---|---|
ReceptorCount | This receptor count is applied when a new sensor is created. |
Width (Line) | The distance between the leftmost and the rightmost receptor. |
Y-Position (Line) | An offset which is applied to the position of every receptor in the newly created sensor. |
Radius (Circle) | Receptors are distributed equally on a circle defined by this radius. |
Simply set the ReceptorCount
as needed, then, set the parameters of either the line or the circle as you like and hit the Create New button. Note that there must be at least 1 receptor. If you want to have more control over how a sensor is shaped, have a look at the Planar Shaper.
For visualization, you can use the sensor gizmo. This gizmo is always rendered at the center of the currently opened scene.
Property | Description |
---|---|
Enabled | Determines whether to display the gizmo. |
Scale | Visually scales the gizmo on screen. |
Color | Sets the color for the displayed receptors. |
A receptor is one single part of a sensor forming the actual sensor. So what a sensor pixel means for a camera sensor, a receptor means for a Polarith AI sensor. For each receptor, the associated sensor stores specific data, like directional vectors, as well as neighbourhood information forming a certain sensor shape which determines how an agent can observe the world.
All receptor data (but not the objective values) are stored within the sensor, and thus, the data can be shared between different agents using the same sensor. Though, it is possible to automatically create copies (clones) at runtime if you want to modify sensors dynamically without affecting other agents, therefore see SensorShared
in Context.
Data | Description |
---|---|
Position | Offset to the local position of the sensor. Note, behaviours using forEachPercept ignore this value. |
Direction | The normalized direction of this receptor. This is always of type Vector3 . |
MagnitudeMultiplier | The global multiplier for this receptor, it can be interpreted as weight. |
Sensitiviy | The maximum angle for this receptor to recognize a behaviour's ResultDirection for writing objective values. |
Every receptor stores a list of neighbourhood indices. In theory, every receptor can have an arbitrary amount of neighbours. For a better usability, we decided our (planar) behaviours to work under the assumption that there is always one preceding and one subsequent neighbour. This fact, together with the intension that every receptor position within a sensor lies in the same plane, is our definition of planar. The specific neighbour index can also be -1 if no other receptor is adjacent. That said, you are able to change the neighbourhood structure if you want, but then, we do not guarantee our behaviours to work (especially the behaviours marked with planar).