Class FollowerEntity Extends VersionedMonoBehaviour, IAstarAI, ISerializationCallbackReceiver

Public

Movement script that uses ECS.

This script is a replacement for the AIPath and RichAI scripts.

This script is a movement script. It takes care of moving an agent along a path, updating the path, and so on.

The intended way to use this script is to use these two components:

Of note is that this component shouldn't be used with a Seeker component. It has its own settings for pathfinding instead, which are stored in the pathfindingSettings field.

Features

  • Uses Unity's ECS (Entity Component System) to move the agent. This means it is highly-performant and is able to utilize multiple threads. You do not need to know anything about ECS to be able to use it.

  • Supports local avoidance (see Local Avoidance).

  • Supports movement in both 2D and 3D games.

  • Supports movement on spherical on non-planar worlds (see Spherical Worlds).

  • Supports movement on grid graphs as well as navmesh/recast graphs.

  • Does not support movement on point graphs at the moment. This may be added in a future update.

  • Supports time-scales greater than 1. The agent will automatically run multiple simulation steps per frame if the time-scale is greater than 1, to ensure stability.

  • Supports off-mesh links. See Off-mesh links for more info.

  • Knows which node it is traversing at all times (see currentNode).

  • Automatically stops when trying to reach a crowded destination when using local avoidance.

  • Clamps the agent to the navmesh at all times.

  • Follows paths very smoothly.

  • Can keep a desired distance to walls.

  • Can approach its destination with a desired facing direction.

Inspector

Shape

Radius

Radius of the agent in world units.

Height

Height of the agent in world units.

Orientation

Determines which direction the agent moves in.

Movement

Speed

Max speed in world units per second.

Rotation Speed

Desired rotation speed in degrees per second.

Max Rotation Speed

Maximum rotation speed in degrees per second.

Allow Rotating On The Spot

If rotation on the spot is allowed or not.

Max On Spot Rotation Speed

Maximum rotation speed in degrees per second while rotating on the spot.

Slowdown Time When Turning On Spot

Time for the agent to slow down to a complete stop when rotating on the spot.

Position Smoothing

How much to smooth the visual position of the agent.

Rotation Smoothing

How much to smooth the visual rotation of the agent.

Slowdown Time

Time for the agent to slow down to a complete stop when it approaches the destination point, in seconds.

Stop Distance

How far away from the destination should the agent aim to stop, in world units.

Lead In Radius When Approaching Destination

How wide of a turn to make when approaching a destination for which a desired facing direction has been set.

Desired Wall Distance

How big of a distance to try to keep from obstacles.

Gravity

Enables or disables gravity.

Raycast Ground Mask

Determines which layers the agent will stand on.

Movement Plane Source

How to calculate which direction is "up" for the agent.

Pathfinding

Traversable Graphs

Graphs that this agent can use.

Tags/Penalty

The penalty for each tag.

Tags/Traversable

The tags which this agent can traverse.

Recalculate Paths Automatically

Policy to use when recalculating paths.

Period

Number of seconds between each automatic path recalculation for Mode.EveryNSeconds, and the maximum interval for Mode.Dynamic.

Local Avoidance

Enable Local Avoidance

True if local avoidance is enabled for this agent.

Agent Time Horizon

How far into the future to look for collisions with other agents (in seconds)

Obstacle Time Horizon

How far into the future to look for collisions with obstacles (in seconds)

Max Neighbours

Max number of other agents to take into account.

Layer

Specifies the avoidance layer for this agent.

Collides With

Layer mask specifying which layers this agent will avoid.

Priority

How strongly other agents will avoid this agent.

Locked

A locked unit cannot move.

Debug

Movement Debug Rendering

Enables or disables debug drawing for this agent.

Local Avoidance Debug Rendering

Enables drawing debug information in the scene view.

Reached Destination

True if the ai has reached the destination.

Reached End Of Path

True if the agent has reached the end of the current path.

Has Path

True if this agent currently has a valid path that it follows.

Path Pending

True if a path is currently being calculated.

Destination

Position in the world that this agent should move to.

Remaining Distance

Approximate remaining distance along the current path to the end of the path.

Speed

Actual velocity that the agent is moving with.

ECS

This script uses Unity's ECS (Entity Component System) to move the agent. This means it is highly-performant and is able to utilize multiple threads. Internally, an entity is created for the agent with the following components:

Then this script barely does anything by itself. It is a thin wrapper around the ECS components. Instead, actual movement calculations are carried out by the following systems:

In fact, as long as you create the appropriate ECS components, you do not even need this script. You can use the systems directly.

This is not a baked component. That is, this script will continue to work even in standalone games. It is designed to be easily used without having to care too much about the underlying ECS implementation.

Differences compared to AIPath and RichAI

This movement script has been written to remedy several inconsistency issues with other movement scrips, to provide very smooth movement, and "just work" for most games.

For example, it goes to great lengths to ensure that the reachedDestination and reachedEndOfPath properties are as accurate as possible at all times, even before it has had time to recalculate its path to account for a new destination. It does this by locally repairing the path (if possible) immediately when the destination changes instead of waiting for a path recalculation. This also has a bonus effect that the agent can often work just fine with moving targets, even if it almost never recalculates its path (though the repaired path may not always be optimal), and it leads to very responsive movement.

In contrast to other movement scripts, this movement script does not use path modifiers at all. Instead, this script contains its own internal FunnelModifier which it uses to simplify the path before it follows it. In also doesn't use a separate RVOController component for local avoidance, but instead it stores local avoidance settings in rvoSettings.

Best practices for good performance

Here are some tips for how to improve performance when using this script. As always, make sure to profile your game first, to see what is actually causing performance problems.

Disable unused features
This script has some optional parts. Local avoidance, for example. Local avoidance is used to make sure that agents do not overlap with each other. However, if you do not need it, you can disable it to improve performance.

Don't change the destination unnecessarily
Repairing the path each frame can be a significant part of the movement calculation time. The FollowerEntity will perform better if the destination is static, or moves seldom. For example, updating the destination every 10 frames will be faster than updating it every frame, but to the player, both will look basically the same.

Note

Repairing the path is different from recalculating it from scratch. The agent will recalculate the path from scratch relatively seldom, but it will repair it every frame, if necessary, to account for small changes in the agent's position and destination.

Disable debug rendering
Debug rendering has some performance costs in the Unity Editor. Disable all debugFlags and rvoSettings.debug to improve performance. However, in standalone builds, these are automatically disabled and have no cost.

Be aware of property access costs
Using ECS components has some downsides. Accessing properties on this script is significantly slower compared to accessing properties on other movement scripts. This is because on each property access, the script has to make sure no jobs are running concurrently, which is a relatively expensive operation. Slow is a relative term, though. This only starts to matter if you have lots of agents, maybe a hundred or so. So don't be scared of using it.

But if you have a lot of agents, it is recommended to not access properties on this script more often than required. Avoid setting fields to the same value over and over again every frame, for example. If you have a moving target, try to use the AIDestinationSetter component instead of setting the destination property manually, as that is faster than setting the destination property every frame.

You can instead write custom ECS systems to access the properties on the ECS components directly. This is much faster. For example, if you want to make the agent follow a particular entity, you could create a new DestinationEntity component which just holds an entity reference, and then create a system that every frame copies that entity's position to the DestinationPoint.destination field (a component that this entity will always have).

Public Methods

GetRemainingPath (buffer, [partsBuffer], stale)

Fills buffer with the remaining path.

Move (deltaPosition)

Move the agent.

Recalculate the current path.

SetDestination (destination, facingDirection=…)

Set the position in the world that this agent should move to.

SetPath ([entity], path, [updateDestinationFromPath])

Make the AI follow the specified path.

Teleport (newPosition, clearPath=true)

Instantly move the agent to a new position.

Public Static Methods

CreateEntity (position, rotation, scale, shape, movement, autoRepath, managedState, orientation, movementPlaneSource, updatePosition, updateRotation, physicsScene)

Creates an entity with the given data.

Public Variables

autoRepath

Policy for when the agent recalculates its path.

Public
canMove

Enables or disables movement completely.

Public
currentNode

Node which the agent is currently traversing.

Public
debugFlags

Enables or disables debug drawing for this agent.

Public
desiredVelocity

Velocity that this agent wants to move with.

Public
desiredVelocityWithoutLocalAvoidance

Velocity that this agent wants to move with before taking local avoidance into account.

Public
destination

Position in the world that this agent should move to.

Public
enableGravity

Enables or disables gravity.

Public
enableLocalAvoidance

True if local avoidance is enabled for this agent.

Public
endOfPath

End point of path the agent is currently following.

Public
entity

Entity which this movement script represents.

Public
entityExists

True if this component's entity exists.

Public
groundMask

Determines which layers the agent will stand on.

Public
hasPath

True if this agent currently has a valid path that it follows.

Public
height

Height of the agent in world units.

Public
isStopped

Gets or sets if the agent should stop moving.

Public
isTraversingOffMeshLink

True if the agent is currently traversing an off-mesh link.

maxRotationSpeed

Maximum rotation speed in degrees per second.

Public
maxSpeed

Max speed in world units per second.

Public
movementOverrides

Provides callbacks during various parts of the movement calculations.

Public
movementPlane

The plane the agent is moving in.

Public
movementPlaneSource

How to calculate which direction is "up" for the agent.

Public
movementSettings

Various movement settings.

Public
offMeshLink

The off-mesh link that the agent is currently traversing.

onTraverseOffMeshLink

Callback to be called when an agent starts traversing an off-mesh link.

orientation

Determines which direction the agent moves in.

Public
pathPending

True if a path is currently being calculated.

Public
pathfindingSettings

Pathfinding settings.

Public
position

Position of the agent.

Public
positionSmoothing

How much to smooth the visual position of the agent.

Public
radius

Radius of the agent in world units.

Public
reachedDestination

True if the ai has reached the destination.

Public
reachedEndOfPath

True if the agent has reached the end of the current path.

Public
remainingDistance

Approximate remaining distance along the current path to the end of the path.

Public
rotation

Rotation of the agent.

Public
rotationSmoothing

How much to smooth the visual rotation of the agent.

Public
rotationSpeed

Desired rotation speed in degrees per second.

Public
rvoSettings

Local avoidance settings.

Public
steeringTarget

Point on the path which the agent is currently moving towards.

Public
stopDistance

How far away from the destination should the agent aim to stop, in world units.

Public
updatePosition

Determines if the character's position should be coupled to the Transform's position.

Public
updateRotation

Determines if the character's rotation should be coupled to the Transform's rotation.

Public
velocity

Actual velocity that the agent is moving with.

Public

Private/Protected Members

Awake ()
ClearPath ([...])
FinalizeMovement (nextPosition, nextRotation)

Move the agent.

FollowerEntityMigrations
Private
MovementUpdate (deltaTime, nextPosition, nextRotation)

Calculate how the character wants to move during this frame.

Called when the component is disabled or about to be destroyed.

OnUpgradeSerializedData (migrations, unityThread)

Reset ()

Handle serialization backwards compatibility.

ResetControl (resolvedMovement, controlOutput, movementPlane, position, rotation, endOfPath)
ScratchNNConstraint

Cached NNConstraint, to avoid allocations.

Private Static
ShapeGizmoColor
Private Static Readonly
Start ()
ToggleComponent<T> (entity, enabled, mustExist)

Adds or removes a component from an entity.

ToggleComponentEnabled<T> (entity, enabled, mustExist)

Enables or disables a component on an entity.

UpgradeSerializedData (isUnityThread)
achetypeWorld
Private Static
agentCylinderShapeAccessRO
Private Static
agentCylinderShapeAccessRW
Private Static
agentOffMeshLinkTraversalRO
Private Static
archetype
Private Static
autoRepathBacking
Private
autoRepathPolicyRW
Private Static
destinationFacingDirection

Direction the agent will try to face when it reaches the destination.

Private
destinationPointAccessRO
Private Static
destinationPointAccessRW
Private Static
entityStorageCache
Private Static
indicesScratch
Private Static
localTransformAccessRO
Private Static
localTransformAccessRW
Private Static
managedState
Private
managedStateAccessRO
Private Static
managedStateAccessRW
Private Static
movement
Private
movementControlAccessRO
Private Static
movementControlAccessRW
Private Static
movementOutputAccessRW
Private Static
movementPlaneAccessRO
Private Static
movementPlaneAccessRW
Private Static
movementPlaneSourceBacking
Private
movementSettingsAccessRO
Private Static
movementSettingsAccessRW
Private Static
movementStateAccessRO
Private Static
movementStateAccessRW
Private Static
movementStatisticsAccessRW
Private Static
nextCornersScratch
Private Static
onSearchPath

Called when the agent recalculates its path.

Private
orientationBacking

Determines which direction the agent moves in.

Private
readyToTraverseOffMeshLinkRW
Private Static
resolvedMovementAccessRO
Private Static
resolvedMovementAccessRW
Private Static
scratchReferenceCount
Private Static
shape
Private
syncPosition

Determines if the character's position should be coupled to the Transform's position.

Private
syncRotation

Determines if the character's rotation should be coupled to the Transform's rotation.

Private
tr

Cached transform component.

Private

Deprecated Members

canSearch

Enables or disables recalculating the path at regular intervals.

Public