Class FollowerEntity Extends VersionedMonoBehaviour, IAstarAI, ISerializationCallbackReceiver

Public

Movement script that uses ECS.

Warning

This script is still in beta and may change in the future. It aims to be much more robust than AIPath/RichAI, but there may still be rough edges.

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 instead has its own settings for pathfinding, 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.

  • 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. Subscribe to the onTraverseOffMeshLink event to handle this.

  • 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.

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

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).

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

Public Methods

DrawGizmos ()
Public
GetRemainingPath (buffer, stale)

Fills buffer with the remaining path.

Public
GetRemainingPath (buffer, partsBuffer, stale)

Fills buffer with the remaining path.

Public
Move (deltaPosition)

Move the agent.

Public
SearchPath ()

Recalculate the current path.

Public
SetDestination (destination, facingDirection=…)

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

Public
SetPath (path, updateDestinationFromPath=true)

Make the AI follow the specified path.

Public
Teleport (newPosition, clearPath=true)

Instantly move the agent to a new position.

Public

Public Static Methods

SetPath (entity, path, updateDestinationFromPath=true)

Make the AI follow the specified path.

Public Static

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.

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
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
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

AssertEntityExists ()
Private
Awake ()
Protected
CancelCurrentPathRequest ()
Private
ClearPath ()
Private
ClearPath (entity)
Private Static
FinalizeMovement (nextPosition, nextRotation)

Move the agent.

Private
FindComponents ()
Private
FollowerEntityMigrations
Private
MovementUpdate (deltaTime, nextPosition, nextRotation)

Calculate how the character wants to move during this frame.

Private
OnDisable ()

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

Private
OnEnable ()
Private
OnUpgradeSerializedData (migrations, unityThread)
Protected
OnUpgradeSerializedData (migrations, unityThread)

Handle serialization backwards compatibility.

Protected
RegisterRuntimeBaker (baker)
Internal
Reset ()

Handle serialization backwards compatibility.

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

Adds or removes a component from an entity.

Private Static
UpgradeSerializedData (isUnityThread)
Protected
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
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
tr

Cached transform component.

Private

Deprecated Members

canSearch

Enables or disables recalculating the path at regular intervals.

Public