A toolbox of generic sensor components that are like eyeballs for GameObjects. Give your games the power of ‘seeing’ with a reusable set of lightweight sensor components.
Game behaviour often requires awareness of the game world:
Sensors detect GameObjects and maintain a list of detected GameObjects. Objects are added to this list when they are newly detected by the sensor, and remain on the list up until the sensor loses tracking of them, for example if the object moved out of range. How they detect GameObjects depends on the sensors implementation and your configurations. They provide methods to query and filter which GameObjects are detected, and events for when new detections are made or existing detections are lost. To this end each sensor type extends a common base component: SensorToolkit.Sensor.
Here's how you might write a MonoBehaviour that uses a sensor. This sensor could be placed at the end of a maze to check if the player has reached the last room and escaped.
using UnityEngine;
using System.Collections;
using SensorToolkit;
public class EscapeRoom : MonoBehaviour
{
Sensor sensor;
bool hasEscaped = false;
void Awake()
{
// RaySensor, RangeSensor and TriggerSensor all extend Sensor
sensor = GetComponent<Sensor>();
}
void Update()
{
// GetNearestByName returns the nearest detected GameObject with the specified name, or null if there is none detected.
if (sensor.GetNearestByName("Player") != null)
{
hasEscaped = true;
}
}
}
Sensors update their list of detected GameObjects by being pulsed, that is by having their Pulse() method called. This will cause the sensor to perform its 'sensing' routine that adds and removes GameObjects from its list of detected objects. Each of the sensors can be configured to automatically pulse themselves at fixed intervals or every frame. Sometimes however you may want precise control over when a sensor is pulsed, for example a bullet may want to pulse its sensor just before it determines whether it has hit anything. In this example you could disable automatic pulsing on the bullet's sensor and manually call Pulse() when needed.
Each of the sensors detect GameObjects by their colliders, but that doesn't mean the collider itself will appear in the sensors list of detected objects. Each sensor has two detection modes: Colliders or RigidBodies.
Base behaviour extended by all sensors.
| Returns a list of all GameObjects detected by the Sensor in no particular order. The same list object is returned each time. |
| Returns an list of all GameObjects detected by the Sensor in order of distance from the Sensor. The same list object is returned each time. |
| Invoked when a new GameObject is detected. |
| Invoked when a GameObject that was detected is no longer detected. |
|
Returns true if the GameObject is detected by the Sensor. |
|
Only relevant when line of sight testing is enabled. Returns the computed visibility of a GameObject between 0 and 1. |
|
Causes the sensor to perform it's 'sensing' routine, so that its list of detected objects is updated. Each sensor can be configured to pulse automatically. If you need more control over when the sensor updates then you can call this method manually. |
|
Returns a list of all Detected GameObjects ordered by distance with various filters such as by name, tag or component. More methods exist then shown here for combining filters. |
|
Returns the nearest Detected GameObject filtered by name, tag and component or null if there isn't one. Like above more methods exist then shown here for combining filters. |
|
Returns the nearest detected GameObject to a given world position filtered by name, tag and component. Like above more methods exist then shown here for combining filters. |
A Ray Sensor detects GameObjects along a straight line. It uses either a Physics.Raycast or Physics.SphereCast test dependong on its configurations. A Ray Sensor is defined by its length, radius, the physics layers that it detects GameObjects on, and the physics layers that blocks it's path.
Length | The length of the ray in world units. |
Radius | The radius of the ray in world units. If greater than 0 the sensor will perform a sphere cast. |
Ignore List | Any GameObject in this list will not show as a detected object. Useful to stop GameObjects detecting themselves. |
Enable Tag Filter | When checked the sensor will only detect objects with specific tags. |
Allowed Tags | If tag filtering is enabled the sensor will only detect objects with a tag in this list. |
Obstructed By Layers | The Ray Sensor will be obstructed by any collider in these layers. |
Detects On Layers | The Ray Sensor detects GameObjects on these layers. |
Detection Mode |
|
Direction | What direction the ray sensor is pointing. |
World Space | Is the direction parameter in world space or local space. |
Sensor Update Mode |
|
Initial Buffer Size | To avoid memory allocations the ray uses Physics.RaycastNonAlloc and Physic.SphereCastNonAlloc. This is the initial size of the buffer used to store results. If you know a sensor will detect many objects you may want to increase this. |
Dynamically Increase Buffer Size | When true the buffer size will be extended when a Raycast or SphereCast is performed and the buffer is not sufficently large to store all results. The buffer size is doubled and the raycast is performed again. If this is false the buffer size is fixed. |
The RaySensor behaviour has some extra functionality on top of the SensorToolkit.Sensor behaviour.
| Returns a list of all the RaycastHit objects for all the detected GameObjects. There is only one hit per GameObject and they're returned in no particular order. |
| Returns the collider that obstructed the Ray Sensor if there is one, null otherwise. |
| Returns the RaycastHit object for the raycast result that obstructed the RaySensor. |
| Returns true if something obstructed the Ray Sensor. |
| Event fired when the ray sensor becomes obstructed. |
| Event fired when the ray sensor becomes clear of obstructions. |
| Returns the RaycastHit object for a detected GameObject. |
A Range Sensor detects GameObjects within a specified distance from the sensor. It uses the Physics.OverlapSphereNonAlloc method to detect colliders on the configured physics layers. It can be set to pulse automatically at fixed intervals and has optional support for line of sight testing.
The Range Sensor has optional support for line of sight testing. When enabled a GameObject must additionally pass a line of sight test in order to be detected. A number of raycasts will be performed from the sensors origin towards test points on the GameObject. The fraction of rays that are unobstructed determines the GameObjects visibility. When the visibility is greater then a configured threshold then the GameObject is detected.
By default the test points on a GameObject are randomly generated, but you can choose the test points on a GameObject yourself by giving it a LOSTargets component.
Sensor Range | The range of the sensor in world units. |
Detects On Layers | The Range Sensor detects colliders on these layers. |
Ignore List | Any GameObject in this list will not show as a detected object. Useful to stop GameObjects detecting themselves. |
Enable Tag Filter | When checked the sensor will only detect objects with specific tags. |
Allowed Tags | If tag filtering is enabled then the sensor will only detect objects whose tags are in this list. |
Detection Mode |
|
Sensor Update Mode |
|
Check Interval | If set to pulse at a fixed interval this is the time in seconds between updates. |
Requires Line Of Sight | When actived then GameObjects must also pass a line of sight test to be detected. |
Blocks Line Of Sight | The physics layers that block line of sight tests. |
Test LOS Targets Only | When checked the sensor will only perform line of sight tests on object with an LOSTargets component, if the object doesn't have this component then it won't be detected. If unchecked the sensor will generate random test points on objects that don't have a LOSTargets component. |
Number of Rays | The number of raycast test points that are generated on objects for performing line of sight tests. Only relevant on objects without a LOSTarget component. |
Minimum Visibility | The fraction of rays that must be unobstructed for the GameObject to be detected. |
Initial Buffer Size | To avoid memory allocations the sensor uses Physics.OverlapSphereNonAlloc. This is the initial size of the buffer used to store results. If you know a sensor will detect many objects you may want to increase this. |
Dynamically Increase Buffer Size | When true the buffer size will be extended when a pulse is performed and the buffer is not sufficently large to store all results. The buffer size is doubled and sensor pulsed again. If this is false the buffer size is fixed. |
The Range Sensor behaviour has some extra functionality on top of the SensorToolkit.Sensor behaviour.
| Returns a list of all test transforms on the specified GameObject that passed line of sight tests. These test transforms are taken from the objects LOSTargets component, therefore it must have a LOSTargets component. |
| Returns a list of all test positions on the specified GameObject that passed line of sight tests. These test positions were either taken from the GameObjects LOSTargets component if it has one, or they were randomly generated by the sensor. |
Trigger Sensors use trigger colliders to detect GameObjects making them the most robust sensor solution but requiring the most care to set up, otherwise you may find them detecting things you don't want them to. They listen for OnTriggerEnter and OnTriggerExit events to detect GameObjects as soon as their colliders intersect with the sensor. They can use any trigger collider or even multiple trigger colliders to make up their sensor volume.
The Trigger Sensor also has optional support for line of sight testing. When enabled a GameObject must additionally pass a line of sight test in order to be detected. A number of raycasts will be performed from the sensors origin towards test points on the GameObject. The fraction of rays that are unobstructed determines the GameObjects visibility. When the visibility is greater then a configured threshold then the GameObject is detected.
By default the test points on a GameObject are randomly generated, but you can choose the test points on a GameObject yourself by giving it a LOSTargets component.
When LOS is disabled the Pulse method does nothing because GameObjects are detected immediately when they intersect the sensor. If LOS is enabled then the sensor must be pulsed in order to perform line of sight tests.
To get the most out of Trigger Sensors it's important to set up your physics layers correctly. I recommend creating a new physics layer just for sensors that can collide with your existing game layers, but cannot collide with itself. Assign your Trigger Sensors to this layer, set it on the GameObject which holds the Trigger Sensor component.
Ignore List | Any GameObject in this list will not show as a detected object. Useful to stop GameObjects detecting themselves. |
Enable Tag Filter | When checked the sensor will only detect objects with specific tags. |
Allowed Tags | If tag filtering is enabled then the sensor will only detect objects whose tags are in this list. |
Detection Mode |
|
Requires Line Of Sight | When actived then GameObjects must also pass a line of sight test to be detected. |
Blocks Line Of Sight | The physics layers that block line of sight tests. |
Line Of Sight Update Mode |
|
Check Line Of Sight Interval | If set to refresh line of sight at a fixed interval this is the time in seconds between updates. |
Test LOS Targets Only | When checked the sensor will only perform line of sight tests on object with an LOSTargets component, if the object doesn't have this component then it won't be detected. If unchecked the sensor will generate random test points on objects that don't have a LOSTargets component. |
Number of Rays | The number of raycast test points that are generated on objects for performing line of sight tests. Only relevant on objects without a LOSTarget component. |
Minimum Visibility | The fraction of rays that must be unobstructed for the GameObject to be detected. |
The Trigger Sensor behaviour has some extra functionality on top of the SensorToolkit.Sensor behaviour.
| Returns a list of all test transforms on the specified GameObject that passed line of sight tests. These test transforms are taken from the objects LOSTargets component, therefore it must have a LOSTargets component. |
| Returns a list of all test positions on the specified GameObject that passed line of sight tests. These test positions were either taken from the GameObjects LOSTargets component if it has one, or they were randomly generated by the sensor. |
A steering rig is used to compute steering vectors, so that gameobjects are able to navigate around obstacles. Assume you have a character that wants to move in some direction, the steering rig will push that direction depending on the obstacles around it, resulting in a vector that should be in a similar general direction, but clear of nearby obstacles.
The rig computes its steering vectors using a set of ray sensor components on child transforms. You are free to create as many ray sensors as you'd like, and you may orient them how you like. There are some premade steering rig prefabs under the SensorToolkit/SteeringRigPrefabs/ folder, I recommend using one of these as a template.
The steering rig has two modes of operation: you can use it as a simple movement system by assigning a rigid body to control, or you can use it for calculating steering vectors only by leaving the rigid body field blank. If you leave it blank then you are using only the 'sensing' capability of the steering rig whilst retaining full control over your characters movement. Have your character tell the sensor what direction it wants to move, and the sensor will calculate the direction it should move instead so that it avoids nearby obstacles. The Examples/Action example uses the steering rig in this way.
If you use the rig as a movement system then you can give it a destination and the rig will try to move there while avoiding obstacles. Both the Examples/Stealth and Examples/Space use the rig as a movement system as well.
You are free to orient the ray sensors composing the steering rig however you like. For example you could add some sensors at head level on the character steering rig above in order to avoid obstacles on the ceiling.
The steering rig is composed of ray sensors for calulating steered vectors. When any of these ray sensors are obstructed it will affect the direction of the steered vector. You must configure these ray sensors to control what objects the steering rig will avoid.
Ignore List | GameObjects in this list are injected into the ignore lists of the child ray sensors, so they won't affect the steering rig. |
Avoidance Sensitivity | At higher values the steering rig will try to keep a larger distance from obstacles. |
Max Avoidance Length | Controls how far a direction can be pushed when the rigs ray sensors are obstructed by obstacles. |
Y Axis | Whether the steering rig should steer across all three axes or be confined to the x-z plane. This should be turned off for characters that are confined to walk along the ground. This should be turned on for flying units. |
Rotate Towards Target | When enabled the rig will rotate to face the target direction before determining if its ray sensors are obstructed. This is useful for making asymmetric steering rigs where the majority of ray sensors are facing forwards. All of the included steering rig prefabs have this enabled. |
RB | *Optional* attach a rigid body here and the steering rig will move it for you. Supports kinematic and non-kinematic rigid bodies. |
Turn Force/Turn Speed | If a rigid body is attached this is the maximum force/speed to turn it. |
Move Force/Move Speed | If a rigid body is attached this is the maximum force/speed to move it in a forwards direction. |
Strafe Force/Strafe Speed | If a rigid body is attached this is the maximum force/speed to move it in any direction other than forwards. |
Stopping Distance | If a rigid body is attached this is the minimum distance to reach a destination position. |
Destination Transform | If a rigid body is attached the rig will try to move it towards this transform. |
Face Towards Transform | If a rigid body is attached the rig will turn it to face this transform. This may cause it to strafe if its moving in a different direction. |
The public interface of the steering rig component.
| The destination position that the steering rig is seeking towards. |
| True when the steering rig is moving its attached rigid body towards its destination. |
| The direction that the steering rig should face towards. If none is set this returns Vector3.zero. |
| True when the steering rig is instructed to face a particular direction. |
| Steers the targetDirection vector and returns a vector in the same general direction but clear of obstacles. If you haven't attached a rigid body because you want to control movement yourself then this is the only method you need to call. |
| Clears the DirectionToFace requirement, enabling the default behaviour where the rig turns its rigid body to face towards its destination. |
The FOVCollider is a parametric collider shape designed to create field of view cones for the trigger sensor. You can change the shape of the collider by adjusting it's values in the editor.
Length | The radius of the field of view arc. |
Base Size | The size of the base. |
FOV Angle | The field of view angle. |
Resolution | The number of vertices used to approximate the field of view arc. Ideally this should be as low as possible. |
The LOSTargets component lets you specify your own points on a target object that should be used for line of sight testing. When a sensor detects a GameObject it first checks for this component and performs a ray test against each user defined entry. If the Sensor doesn't find a LOSTargets component then it reverts to randomly generating points on the object.
Sensor Toolkit ships with custom playmaker actions to help you create beautifully simple FSMs.
The custom actions have similar functionality to the methods described on the sensor pages. Just search for actions in the 'Sensor' category.
If you have questions, feature requests or would like to report a bug then please email me at micosmogames@gmail.com