Entities
For those who plan to use Entities in your project or want to squeeze as much performance as possible, you can directly use entities and their agent components. All you need to do is add your Agents to a SubScene, and they get automatically baked into the correct entity components.
For those who want to create agent entities without the baker workflow, I recommend looking up game object authoring bakers to see the reference for which entity components to add with default fields.
Also, each entity component has a static property named Default to simplify the creation of it instead of figuring out what default fields it requires. The other benefit of using those static properties provides better backward compatibility in case you upgrade to a newer version of agents navigation, and a new field gets added to the component.
var entity = EntityManager.CreateEntity();
// Agent tag is required for agent to work
EntityManager.AddComponentData(entity, Agent.Default);
// AgentBody for dynamic agents
EntityManager.AddComponentData(entity, AgentBody.Default);
// AgentLocomotion for moving
EntityManager.AddComponentData(entity, AgentLocomotion.Default);
// AgentShape for default cylinder shape
EntityManager.AddComponentData(entity, AgentShape.Default);
Important
If you are not familiar with ECS, I highly recommend learning the basics of Entities before continuing with this section.
Architecture
This package architecture is heavily influenced by Craig Reynolds' Boids. Agent navigation is essentially divided into four major sections.
The first one is Action, where the agent performs high-level logic to decide whether it should continue moving or change its destination.
Next is Steering, where the agent attempts to steer towards its destination. The steering force here is a vector used by the agent to move towards it. In most cases, it will be a unit vector, but not necessarily, as a lower length than one can indicate that the agent should slow down. Many systems will modify the steering force, and each system will attempt to refine it to provide more complicated navigation. For example, the steering force can start with very simple seeking logic, where the agent goes straight into the destination. Then a pathing system like navmesh can modify it to account for path following. Furthermore, there can be avoidance, like sonar, that modifies steering to avoid nearby agents. This can continue with multiple systems and even custom ones.
The third section is Locomotion, where the agent uses its steering force to move. There is a default component called AgentLocomotion that simulates a point mass body. To write a custom one, you can check Custom Locomotion.
Finally, Displacement is the final step where the agent typically will be constrained within the navmesh surface or ensure non-overlapping between other agents.
| Sections | System Groups | Details |
|---|---|---|
| Action | Agent Spatial System Group | Constructs accelerated structure for fast nearby agent search |
| Agent Action System Group | High-level decision for navigation | |
| Steering | Agent Seeking System Group | Updates forces to steer towards the destination |
| Agent Pathing System Group | Updates forces to account for path following | |
| Agent Force System Group | Updates forces to account for other behaviors like avoidance, separation... | |
| Locomotion | Agent Locomotion System Group | Moves agent using the forces |
| Displacement | Agent Displacement System Group | Finishing pass like containing agent within the path or collision |
This architecture enables a high level of modularity and performance, allowing you to easily add your custom steering/locomotion or even pathing without modifying the package, as long as you follow proper system grouping.
Debug
In case you find some behaviors working unexpectedly, it is recommended to try debug gizmos functionality. This can be enabled per entity by adding component DrawGizmos to it.