A* Pathfinding Project
4.3.5
The A* Pathfinding Project for Unity 3D
|
Base class for AIPath and RichAI. More...
Base class for AIPath and RichAI.
This class holds various methods and fields that are common to both AIPath and RichAI.
Public Member Functions | |
virtual void | FinalizeMovement (Vector3 nextPosition, Quaternion nextRotation) |
Moves the agent to a position. More... | |
virtual void | FindComponents () |
Looks for any attached components like RVOController and CharacterController etc. More... | |
virtual Vector3 | GetFeetPosition () |
Position of the base of the character. More... | |
virtual void | Move (Vector3 deltaPosition) |
Move the agent. More... | |
void | MovementUpdate (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) |
Calculate how the character wants to move during this frame. More... | |
virtual void | SearchPath () |
Recalculate the current path. More... | |
void | SetPath (Path path) |
Make the AI follow the specified path. More... | |
Quaternion | SimulateRotationTowards (Vector3 direction, float maxDegrees) |
Simulates rotating the agent towards the specified direction and returns the new rotation. More... | |
virtual void | Teleport (Vector3 newPosition, bool clearPath=true) |
Instantly move the agent to a new position. More... | |
Public Attributes | |
bool | canMove = true |
Enables or disables movement completely. More... | |
bool | canSearch = true |
Enables or disables recalculating the path at regular intervals. More... | |
bool | enableRotation = true |
If true, the AI will rotate to face the movement direction. More... | |
float | endReachedDistance = 0.2f |
Distance to the end point to consider the end of path to be reached. More... | |
Vector3 | gravity = new Vector3(float.NaN, float.NaN, float.NaN) |
Gravity to use. More... | |
LayerMask | groundMask = -1 |
Layer mask to use for ground placement. More... | |
float | height = 2 |
Radius of the agent in world units. More... | |
float | maxSpeed = 1 |
Max speed in world units per second. More... | |
IMovementPlane | movementPlane = GraphTransform.identityTransform |
Plane which this agent is moving in. More... | |
OrientationMode | orientation = OrientationMode.ZAxisForward |
Determines which direction the agent moves in. More... | |
float | radius = 0.5f |
Height of the agent in world units. More... | |
float | repathRate = 0.5f |
Determines how often the agent will search for new paths (in seconds). More... | |
RVODestinationCrowdedBehavior | rvoDensityBehavior = new RVODestinationCrowdedBehavior(true, 0.5f, false) |
Controls if the agent slows down to a stop if the area around the destination is crowded. More... | |
bool | updatePosition = true |
Determines if the character's position should be coupled to the Transform's position. More... | |
bool | updateRotation = true |
Determines if the character's rotation should be coupled to the Transform's rotation. More... | |
CloseToDestinationMode | whenCloseToDestination = CloseToDestinationMode.Stop |
What to do when within endReachedDistance units from the destination. More... | |
Static Public Attributes | |
static readonly Color | ShapeGizmoColor = new Color(240/255f, 213/255f, 30/255f) |
Protected Member Functions | |
void | ApplyGravity (float deltaTime) |
Accelerates the agent downwards. More... | |
Vector2 | CalculateDeltaToMoveThisFrame (Vector2 position, float distanceToEndOfPath, float deltaTime) |
Calculates how far to move during a single frame. More... | |
virtual void | CalculatePathRequestEndpoints (out Vector3 start, out Vector3 end) |
Outputs the start point and end point of the next automatic path request. More... | |
void | CancelCurrentPathRequest () |
virtual Vector3 | ClampToNavmesh (Vector3 position, out bool positionChanged) |
Constrains the character's position to lie on the navmesh. More... | |
abstract void | ClearPath () |
Clears the current path of the agent. More... | |
abstract void | MovementUpdateInternal (float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation) |
Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not. More... | |
virtual void | OnDisable () |
virtual void | OnDrawGizmos () |
virtual void | OnDrawGizmosSelected () |
virtual void | OnEnable () |
Called when the component is enabled. More... | |
abstract void | OnPathComplete (Path newPath) |
Called when a requested path has been calculated. More... | |
virtual void | OnUpdate (float dt) |
Called every frame. More... | |
override int | OnUpgradeSerializedData (int version, bool unityThread) |
Handle serialization backwards compatibility. More... | |
Vector3 | RaycastPosition (Vector3 position, float lastElevation) |
Checks if the character is grounded and prevents ground penetration. More... | |
override void | Reset () |
Handle serialization backwards compatibility. More... | |
Quaternion | SimulateRotationTowards (Vector2 direction, float maxDegrees) |
Simulates rotating the agent towards the specified direction and returns the new rotation. More... | |
virtual void | Start () |
Starts searching for paths. More... | |
void | UpdateVelocity () |
Protected Member Functions inherited from VersionedMonoBehaviour | |
virtual void | Awake () |
Protected Attributes | |
CharacterController | controller |
Cached CharacterController component. More... | |
Vector2 | lastDeltaPosition |
Amount which the character wants or tried to move with during the last frame. More... | |
float | lastDeltaTime |
Delta time used for movement during the last frame. More... | |
float | lastRepath = float.NegativeInfinity |
Time when the last path request was started. More... | |
int | prevFrame |
Last frame index when prevPosition1 was updated. More... | |
Vector3 | prevPosition1 |
Position of the character at the end of the last frame. More... | |
Vector3 | prevPosition2 |
Position of the character at the end of the frame before the last frame. More... | |
Rigidbody | rigid |
Cached Rigidbody component. More... | |
Rigidbody2D | rigid2D |
Cached Rigidbody component. More... | |
RVOController | rvoController |
Cached RVOController component. More... | |
Seeker | seeker |
Cached Seeker component. More... | |
Vector3 | simulatedPosition |
Position of the agent. More... | |
Quaternion | simulatedRotation |
Rotation of the agent. More... | |
Transform | tr |
Cached Transform component. More... | |
Vector2 | velocity2D |
Current desired velocity of the agent (does not include local avoidance and physics). More... | |
float | verticalVelocity |
Velocity due to gravity. More... | |
bool | waitingForPathCalculation = false |
Only when the previous path has been calculated should the script consider searching for a new path. More... | |
Properties | |
float | centerOffset [get, set] |
Offset along the Y coordinate for the ground raycast start position. More... | |
Vector3 | desiredVelocity [get] |
Velocity that this agent wants to move with. More... | |
Vector3 | destination [get, set] |
Position in the world that this agent should move to. More... | |
bool | isStopped [get, set] |
Gets or sets if the agent should stop moving. More... | |
System.Action | onSearchPath [get, set] |
Called when the agent recalculates its path. More... | |
Vector3 | position [get] |
Position of the agent. More... | |
abstract bool | reachedDestination [get] |
True if the ai has reached the destination. More... | |
Quaternion | rotation [get] |
Rotation of the agent. More... | |
bool | rotationIn2D [get, set] |
If true, the forward axis of the character will be along the Y axis instead of the Z axis. More... | |
virtual bool | shouldRecalculatePath [get] |
True if the path should be automatically recalculated as soon as possible. More... | |
Transform | target [get, set] |
Target to move towards. More... | |
bool | usingGravity [get, set] |
Indicates if gravity is used during this frame. More... | |
Vector3 | velocity [get] |
Actual velocity that the agent is moving with. More... | |
Properties inherited from VersionedMonoBehaviour | |
int Util.IEntityIndex. | EntityIndex [get, set] |
Internal entity index used by #BurstBatchHelper. More... | |
Properties inherited from IEntityIndex | |
int | EntityIndex [get, set] |
Private Member Functions | |
void | FinalizePosition (Vector3 nextPosition) |
void | FinalizeRotation (Quaternion nextRotation) |
void | Init () |
void | ResetShape () |
Static Private Member Functions | |
static void | OnUpdate (AIBase[] components, int count, BatchedEvents.Event ev) |
Called every frame. More... | |
Private Attributes | |
Vector3 | accumulatedMovementDelta = Vector3.zero |
Accumulated movement deltas from the Move method. More... | |
float | centerOffsetCompatibility = float.NaN |
Vector3 | destinationBackingField = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity) |
Backing field for destination. More... | |
bool | startHasRun = false |
True if the Start method has been executed. More... | |
Transform | targetCompatibility |
|
protected |
Accelerates the agent downwards.
|
protected |
Calculates how far to move during a single frame.
|
protectedvirtual |
Outputs the start point and end point of the next automatic path request.
This is a separate method to make it easy for subclasses to swap out the endpoints of path requests. For example the #LocalSpaceRichAI script which requires the endpoints to be transformed to graph space first.
Reimplemented in LocalSpaceRichAI.
|
protected |
|
protectedvirtual |
Constrains the character's position to lie on the navmesh.
Not all movement scripts have support for this.
position | Current position of the character. |
positionChanged | True if the character's position was modified by this method. |
|
protectedpure virtual |
|
virtual |
Moves the agent to a position.
nextPosition | New position of the agent. |
nextRotation | New rotation of the agent. If enableRotation is false then this parameter will be ignored. |
This is used if you want to override how the agent moves. For example if you are using root motion with Mecanim.
This will use a CharacterController, Rigidbody, Rigidbody2D or the Transform component depending on what options are available.
The agent will be clamped to the navmesh after the movement (if such information is available, generally this is only done by the RichAI component).
|
private |
|
private |
|
virtual |
Looks for any attached components like RVOController and CharacterController etc.
This is done during OnEnable. If you are adding/removing components during runtime you may want to call this function to make sure that this script finds them. It is unfortunately prohibitive from a performance standpoint to look for components every frame.
|
virtual |
Position of the base of the character.
This is used for pathfinding as the character's pivot point is sometimes placed at the center of the character instead of near the feet. In a building with multiple floors the center of a character may in some scenarios be closer to the navmesh on the floor above than to the floor below which could cause an incorrect path to be calculated. To solve this the start point of the requested paths is always at the base of the character.
|
private |
|
virtual |
Move the agent.
deltaPosition | Direction and distance to move the agent in world space. |
This is intended for external movement forces such as those applied by wind, conveyor belts, knockbacks etc.
Some movement scripts may ignore this completely (notably the AILerp script) if it does not have any concept of being moved externally.
The agent will not be moved immediately when calling this method. Instead this offset will be stored and then applied the next time the agent runs its movement calculations (which is usually later this frame or the next frame). If you want to move the agent immediately then call:
void MovementUpdate | ( | float | deltaTime, |
out Vector3 | nextPosition, | ||
out Quaternion | nextRotation | ||
) |
Calculate how the character wants to move during this frame.
deltaTime | time to simulate movement for. Usually set to Time.deltaTime. |
nextPosition | the position that the agent wants to move to during this frame. |
nextRotation | the rotation that the agent wants to rotate to during this frame. |
Note that this does not actually move the character. You need to call FinalizeMovement for that. This is called automatically unless canMove is false.
To handle movement yourself you can disable canMove and call this method manually. This code will replicate the normal behavior of the component:
|
protectedpure virtual |
|
protectedvirtual |
Reimplemented in RichAI.
|
protectedvirtual |
|
protectedvirtual |
Called when the component is enabled.
|
protectedpure virtual |
Called when a requested path has been calculated.
Implemented in AIPath, RichAI, and LegacyAIPath.
|
staticprivate |
Called every frame.
This may be called during FixedUpdate or Update depending on if a rigidbody is attached to the GameObject.
|
protectedvirtual |
Called every frame.
Reimplemented in LegacyAIPath, LocalSpaceRichAI, and LegacyRichAI.
|
protectedvirtual |
Handle serialization backwards compatibility.
Reimplemented from VersionedMonoBehaviour.
|
protected |
Checks if the character is grounded and prevents ground penetration.
position | Position of the character in the world. |
lastElevation | Elevation coordinate before the agent was moved. This is along the 'up' axis of the movementPlane. |
Sets verticalVelocity to zero if the character is grounded.
|
protectedvirtual |
Handle serialization backwards compatibility.
Reimplemented from VersionedMonoBehaviour.
|
private |
|
virtual |
Recalculate the current path.
You can for example use this if you want very quick reaction times when you have changed the destination so that the agent does not have to wait until the next automatic path recalculation (see canSearch).
If there is an ongoing path calculation, it will be canceled, so make sure you leave time for the paths to get calculated before calling this function again. A canceled path will show up in the log with the message "Canceled by script" (see #Seeker.CancelCurrentPathRequest()).
If no destination has been set yet then nothing will be done.
Reimplemented in RichAI.
void SetPath | ( | Path | path | ) |
Make the AI follow the specified path.
In case the path has not been calculated, the script will call seeker.StartPath to calculate it. This means the AI may not actually start to follow the path until in a few frames when the path has been calculated. The #pathPending field will as usual return true while the path is being calculated.
In case the path has already been calculated it will immediately replace the current path the AI is following. This is useful if you want to replace how the AI calculates its paths. Note that if you calculate the path using seeker.StartPath then this script will already pick it up because it is listening for all paths that the Seeker finishes calculating. In that case you do not need to call this function.
If you pass null as a parameter then the current path will be cleared and the agent will stop moving. Note than unless you have also disabled canSearch then the agent will soon recalculate its path and start moving again.
You can disable the automatic path recalculation by setting the canSearch field to false.
Quaternion SimulateRotationTowards | ( | Vector3 | direction, |
float | maxDegrees | ||
) |
Simulates rotating the agent towards the specified direction and returns the new rotation.
direction | Direction in world space to rotate towards. |
maxDegrees | Maximum number of degrees to rotate this frame. |
Note that this only calculates a new rotation, it does not change the actual rotation of the agent. Useful when you are handling movement externally using FinalizeMovement but you want to use the built-in rotation code.
|
protected |
Simulates rotating the agent towards the specified direction and returns the new rotation.
direction | Direction in the movement plane to rotate towards. |
maxDegrees | Maximum number of degrees to rotate this frame. |
Note that this only calculates a new rotation, it does not change the actual rotation of the agent.
|
protectedvirtual |
Starts searching for paths.
If you override this method you should in most cases call base.Start () at the start of it.
Reimplemented in LocalSpaceRichAI.
|
virtual |
Instantly move the agent to a new position.
This will trigger a path recalculation (if clearPath is true, which is the default) so if you want to teleport the agent and change its destination it is recommended that you set the destination before calling this method.
The current path will be cleared by default.
|
protected |
|
private |
Accumulated movement deltas from the Move method.
bool canMove = true |
Enables or disables movement completely.
If you want the agent to stand still, but still react to local avoidance and use gravity: use isStopped instead.
This is also useful if you want to have full control over when the movement calculations run. Take a look at MovementUpdate
bool canSearch = true |
Enables or disables recalculating the path at regular intervals.
Setting this to false does not stop any active path requests from being calculated or stop it from continuing to follow the current path.
Note that this only disables automatic path recalculations. If you call the SearchPath() method a path will still be calculated.
|
private |
|
protected |
Cached CharacterController component.
|
private |
Backing field for destination.
bool enableRotation = true |
If true, the AI will rotate to face the movement direction.
float endReachedDistance = 0.2f |
Distance to the end point to consider the end of path to be reached.
When the end of the path is within this distance then #reachedEndOfPath will return true. When the destination is within this distance then reachedDestination will return true.
Note that the destination may not be reached just because the end of the path was reached. The destination may not be reachable at all.
Vector3 gravity = new Vector3(float.NaN, float.NaN, float.NaN) |
Gravity to use.
If set to (NaN,NaN,NaN) then Physics.Gravity (configured in the Unity project settings) will be used. If set to (0,0,0) then no gravity will be used and no raycast to check for ground penetration will be performed.
LayerMask groundMask = -1 |
Layer mask to use for ground placement.
Make sure this does not include the layer of any colliders attached to this gameobject.
float height = 2 |
Radius of the agent in world units.
This is visualized in the scene view as a yellow cylinder around the character.
|
protected |
Amount which the character wants or tried to move with during the last frame.
|
protected |
Delta time used for movement during the last frame.
|
protected |
Time when the last path request was started.
float maxSpeed = 1 |
Max speed in world units per second.
IMovementPlane movementPlane = GraphTransform.identityTransform |
Plane which this agent is moving in.
This is used to convert between world space and a movement plane to make it possible to use this script in both 2D games and 3D games.
OrientationMode orientation = OrientationMode.ZAxisForward |
Determines which direction the agent moves in.
For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games. For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games.
Using the YAxisForward option will also allow the agent to assume that the movement will happen in the 2D (XY) plane instead of the XZ plane if it does not know. This is important only for the point graph which does not have a well defined up direction. The other built-in graphs (e.g the grid graph) will all tell the agent which movement plane it is supposed to use.
|
protected |
Last frame index when prevPosition1 was updated.
|
protected |
Position of the character at the end of the last frame.
|
protected |
Position of the character at the end of the frame before the last frame.
float radius = 0.5f |
Height of the agent in world units.
This is visualized in the scene view as a yellow cylinder around the character.
This value is currently only used if an RVOController is attached to the same GameObject, otherwise it is only used for drawing nice gizmos in the scene view. However since the height value is used for some things, the radius field is always visible for consistency and easier visualization of the character. That said, it may be used for something in a future release.
float repathRate = 0.5f |
Determines how often the agent will search for new paths (in seconds).
The agent will plan a new path to the target every N seconds.
If you have fast moving targets or AIs, you might want to set it to a lower value.
|
protected |
Cached Rigidbody component.
|
protected |
Cached Rigidbody component.
|
protected |
Cached RVOController component.
RVODestinationCrowdedBehavior rvoDensityBehavior = new RVODestinationCrowdedBehavior(true, 0.5f, false) |
Controls if the agent slows down to a stop if the area around the destination is crowded.
Using this module requires that local avoidance is used: i.e. that an RVOController is attached to the GameObject.
|
static |
|
protected |
Position of the agent.
If updatePosition is true then this value will be synchronized every frame with Transform.position.
|
protected |
Rotation of the agent.
If updateRotation is true then this value will be synchronized every frame with Transform.rotation.
|
private |
True if the Start method has been executed.
Used to test if coroutines should be started in OnEnable to prevent calculating paths in the awake stage (or rather before start on frame 0).
|
private |
|
protected |
Cached Transform component.
bool updatePosition = true |
Determines if the character's position should be coupled to the Transform's position.
If false then all movement calculations will happen as usual, but the object that this component is attached to will not move instead only the position property will change.
This is useful if you want to control the movement of the character using some other means such as for example root motion but still want the AI to move freely.
bool updateRotation = true |
Determines if the character's rotation should be coupled to the Transform's rotation.
If false then all movement calculations will happen as usual, but the object that this component is attached to will not rotate instead only the rotation property will change.
|
protected |
Current desired velocity of the agent (does not include local avoidance and physics).
Lies in the movement plane.
|
protected |
Velocity due to gravity.
Perpendicular to the movement plane.
When the agent is grounded this may not accurately reflect the velocity of the agent. It may be non-zero even though the agent is not moving.
|
protected |
Only when the previous path has been calculated should the script consider searching for a new path.
CloseToDestinationMode whenCloseToDestination = CloseToDestinationMode.Stop |
What to do when within endReachedDistance units from the destination.
The character can either stop immediately when it comes within that distance, which is useful for e.g archers or other ranged units that want to fire on a target. Or the character can continue to try to reach the exact destination point and come to a full stop there. This is useful if you want the character to reach the exact point that you specified.
|
getset |
Offset along the Y coordinate for the ground raycast start position.
Normally the pivot of the character is at the character's feet, but you usually want to fire the raycast from the character's center, so this value should be half of the character's height.
A green gizmo line will be drawn upwards from the pivot point of the character to indicate where the raycast will start.
|
get |
Velocity that this agent wants to move with.
Includes gravity and local avoidance if applicable.
|
getset |
Position in the world that this agent should move to.
If no destination has been set yet, then (+infinity, +infinity, +infinity) will be returned.
Note that setting this property does not immediately cause the agent to recalculate its path. So it may take some time before the agent starts to move towards this point. Most movement scripts have a repathRate field which indicates how often the agent looks for a new path. You can also call the SearchPath method to immediately start to search for a new path. Paths are calculated asynchronously so when an agent starts to search for path it may take a few frames (usually 1 or 2) until the result is available. During this time the #pathPending property will return true.
If you are setting a destination and then want to know when the agent has reached that destination then you could either use reachedDestination (recommended) or check both #pathPending and #reachedEndOfPath. Check the documentation for the respective fields to learn about their differences.
|
getset |
Gets or sets if the agent should stop moving.
If this is set to true the agent will immediately start to slow down as quickly as it can to come to a full stop. The agent will still react to local avoidance and gravity (if applicable), but it will not try to move in any particular direction.
The current path of the agent will not be cleared, so when this is set to false again the agent will continue moving along the previous path.
This is a purely user-controlled parameter, so for example it is not set automatically when the agent stops moving because it has reached the target. Use #reachedEndOfPath for that.
If this property is set to true while the agent is traversing an off-mesh link (RichAI script only), then the agent will continue traversing the link and stop once it has completed it.
The #steeringTarget property will continue to indicate the point which the agent would move towards if it would not be stopped.
|
getset |
Called when the agent recalculates its path.
This is called both for automatic path recalculations (see canSearch) and manual ones (see SearchPath).
|
get |
Position of the agent.
In world space. If updatePosition is true then this value is idential to transform.position.
|
get |
True if the ai has reached the destination.
This is a best effort calculation to see if the destination has been reached. For the AIPath/RichAI scripts, this is when the character is within endReachedDistance world units from the destination. For the AILerp script it is when the character is at the destination (±a very small margin).
This value will be updated immediately when the destination is changed (in contrast to #reachedEndOfPath), however since path requests are asynchronous it will use an approximation until it sees the real path result. What this property does is to check the distance to the end of the current path, and add to that the distance from the end of the path to the destination (i.e. is assumes it is possible to move in a straight line between the end of the current path to the destination) and then checks if that total distance is less than endReachedDistance. This property is therefore only a best effort, but it will work well for almost all use cases.
Furthermore it will not report that the destination is reached if the destination is above the head of the character or more than half the height of the character below its feet (so if you have a multilevel building, it is important that you configure the height of the character correctly).
The cases which could be problematic are if an agent is standing next to a very thin wall and the destination suddenly changes to the other side of that thin wall. During the time that it takes for the path to be calculated the agent may see itself as alredy having reached the destination because the destination only moved a very small distance (the wall was thin), even though it may actually be quite a long way around the wall to the other side.
In contrast to #reachedEndOfPath, this property is immediately updated when the destination is changed.
|
get |
Rotation of the agent.
If updateRotation is true then this value is identical to transform.rotation.
|
getset |
If true, the forward axis of the character will be along the Y axis instead of the Z axis.
|
getprotected |
True if the path should be automatically recalculated as soon as possible.
|
getset |
Target to move towards.
The AI will try to follow/move towards this target. It can be a point on the ground where the player has clicked in an RTS for example, or it can be the player object in a zombie game.
|
getsetprotected |
Indicates if gravity is used during this frame.
|
get |