How Unity Turns a Walkable World into Intelligent Movement

Published:

Unity’s navigation system gives game characters a way to understand and move through their surroundings. Instead of treating movement as a simple command to travel from one coordinate to another, it combines a representation of walkable space, global pathfinding, local steering, obstacle avoidance, and movement simulation.

The system is built from several cooperating parts:

  • NavMesh: A data structure describing the walkable surfaces of a scene and the connections between them.
  • NavMesh Agent: A component for characters that move toward goals while avoiding one another and responding to moving obstacles.
  • Off-Mesh Link: A connection for actions that cannot be represented as ordinary walking, such as jumping across a gap or passing through a door.
  • NavMesh Obstacle: A component used to describe obstacles that agents should avoid while navigating.

The navigation data behind the scene

A NavMesh, short for Navigation Mesh, describes where an agent can stand and move. It is generated, or baked, from the geometry of the level. In Unity, an agent is represented as a cylinder, so the system does not merely ask whether a point on the floor is empty. It tests whether an agent of the specified shape can actually occupy and move through that location.

The resulting walkable locations are connected into a surface laid over the scene geometry. This surface is stored as a collection of convex polygons. Convex polygons are useful because any two points inside the same polygon can be connected without an obstruction lying between them. The NavMesh also records which polygons are neighbours, allowing the navigation system to reason about the walkable area as a connected structure rather than as a collection of unrelated floor fragments.

Walkable areas

This separation between level geometry and navigation data is important. The navigation system works with the baked representation when deciding where an agent may travel, rather than repeatedly analysing every piece of scene geometry during movement.

From a destination to a path

When a path is requested, Unity first maps the agent’s starting position and destination to the nearest suitable NavMesh polygons. It then searches through the neighbouring polygons, beginning at the start and continuing until it reaches the polygon containing the destination.

The visited polygons form a sequence that describes how the agent can cross the level. Unity uses the A* algorithm, pronounced “A star,” as a common method for finding this route. The result is not initially a simple list of points for the character to follow. It is a chain of connected navigation polygons.

Finding a path

That polygon sequence is known as a corridor. The agent follows the corridor by steering toward the next visible corner on the route. In a very simple scene with only one moving character, it would be possible to calculate all of the corridor’s corners at once and move the character along the line segments between them.

That approach becomes much less reliable when several agents are moving simultaneously. Characters may need to move away from those original line segments to avoid one another, and continually repairing a fixed corner-to-corner path can quickly become complicated and error-prone.

Because an agent usually moves only a small distance during a single frame, Unity can use the connectivity of the NavMesh polygons to update the corridor locally when a detour is needed. Once the corridor has been adjusted, the system can quickly identify the next visible corner for the agent to steer toward.

Following a navigation corridor

Steering and avoiding other agents

Steering begins with the position of the next corner in the corridor. From that position, the system calculates the direction and speed—or velocity—that would normally be needed to reach it. Simply applying this desired velocity, however, could cause the agent to collide with another character or with the boundary of the navigable area.

Obstacle avoidance therefore selects a new velocity. This velocity balances two competing goals: continuing toward the desired direction and reducing the likelihood of future collisions with other agents or with the edges of the NavMesh.

Unity uses reciprocal velocity obstacles, commonly abbreviated as RVO, to predict and avoid collisions. Rather than waiting until agents overlap and then trying to correct the problem, the method considers their movement and chooses velocities that help them pass around one another.

Local obstacle avoidance

The distinction between the desired velocity and the final velocity is significant. The path tells the agent where it should generally go, while local avoidance determines how it can move there safely in the current frame.

Simulating the final movement

After steering and obstacle avoidance have been applied, Unity calculates the agent’s final velocity. The agent is then simulated using a simple dynamic model that also takes acceleration into account. This produces movement that is more natural and smoother than instantly changing the character’s speed or direction.

At this stage, the simulated velocity can be passed to the Mecanim animation system so that a character’s animation reflects its movement. Alternatively, the navigation system can handle the agent’s movement directly.

Once the agent has been moved through either approach, its simulated position is updated and constrained to the NavMesh. Keeping the position within the navigable surface is a small but important step: it helps maintain stable navigation even when local avoidance or animation-driven movement causes the character to deviate from the ideal route.

Global navigation and local navigation

A central concept in Unity’s navigation system is the distinction between global and local navigation.

Global navigation determines the corridor that connects two locations across the level. Searching for a route through an entire world is relatively expensive because it requires processing the navigation structure and storing the resulting path. This work should not be confused with the frame-by-frame decisions needed to move around nearby characters.

The linear list of polygons that describes the global route is also useful for local steering. As the agent moves, the corridor can be adjusted near the agent’s current position instead of being discarded and rebuilt every time a small detour is required.

Local navigation deals with the immediate movement problem: how to approach the next corner efficiently without colliding with another agent or a moving object. Global navigation answers the question of which broad route to take; local navigation determines how to follow that route in the current moment.

The navigation loop

Keeping these responsibilities separate makes the system more practical. A costly global path search is performed when a route is needed, while local steering and avoidance can respond continuously as nearby conditions change.

Moving and stationary obstacles

Navigation often has to account for more than other agents. Crates, barrels, and vehicles are typical examples of objects that may obstruct a route.

Moving obstacles are generally best handled through local obstacle avoidance. Agents can predict their movement and adjust their velocities without requiring the entire navigation structure to be rebuilt whenever the object changes position. This is especially appropriate for objects controlled by the physics system, such as a barrel or a crate.

A stationary obstacle is different. If it remains in place and effectively blocks the route for all agents, it may need to affect global navigation as well. In that case, the obstacle can modify the NavMesh by creating a hole in the walkable surface.

This process is called carving. The system determines which part of the obstacle overlaps the NavMesh and cuts that area out of the navigation surface. Agents can then recalculate their corridors and route around the newly blocked region, or choose another route if the obstacle completely obstructs the original one.

Carving is computationally expensive because it changes the navigation data itself. That cost is another reason to use local collision avoidance for obstacles that are still moving, and to reserve NavMesh changes for obstacles that have become stationary and should be treated as globally blocking.

Off-Mesh Links and actions beyond walking

A normal NavMesh represents movement across connected walkable surfaces. Some useful actions cannot be expressed that way. An agent may need to jump over a ditch or a fence, pass through a closed doorway, or perform another transition between areas that are not directly connected by walkable ground.

The connections between NavMesh polygons are represented inside the pathfinding system as links. An Off-Mesh Link tells the pathfinder that a route exists across a specified non-walkable section. The link provides the location of the transition, allowing the agent to include it in its path even though the surface itself cannot be traversed by ordinary walking.

When the agent reaches that part of the route, the link can be accessed and a special action can be performed. The navigation system therefore handles the route planning, while the game can provide the appropriate behaviour—such as jumping across the gap, climbing, opening the door, or otherwise completing the transition.

Off-Mesh Links

Together, NavMesh polygons, path corridors, local avoidance, movement simulation, obstacles, and Off-Mesh Links give Unity a layered navigation model. The baked mesh describes where an agent can normally travel, global pathfinding selects a route through that space, and local movement logic keeps the agent moving smoothly as other characters and objects change the immediate situation.