NavMesh in Depth

Tell Unity where characters can walk, give them a destination, and let them find their own way around walls.

A NavMesh is a map of footpaths drawn over your level. An agent is a person holding that map. You point at a spot and say "go there"; the person plans a route and walks it, stepping around other people on the way. The map doesn't decide where to go. That's your game's job.

Package

Install AI Navigation (com.unity.ai.navigation) from the Package Manager. Scripts need using UnityEngine.AI;.

The pieces

ComponentJob
NavMeshSurfaceLooks at your level and bakes (builds) the walkable map.
NavMeshAgentGoes on the character. Plans routes and walks them.
NavMeshObstacleSomething agents should avoid, like a crate or a closed door.
NavMeshLinkA shortcut between two areas that aren't connected, like a jump across a gap.

1. Bake a walkable map

  1. Build a floor and some walls (they need colliders or meshes). Leave a doorway.
  2. Create an empty object called Level, add NavMeshSurface and click Bake.
  3. A blue overlay appears on the floor. That's the walkable area. Check the doorway is blue too.

The blue area stops a little short of walls. That gap is the agent's Radius: room for its body. If a doorway disappears, the agent is too wide for it. Change the radius in the agent settings and bake again.

2. Walk to a target

Add a NavMeshAgent to your character, place it on the blue area, then attach this script and drag a target object into Target.

using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]
public class FollowTarget : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private float repathDelay = 0.25f; // seconds between route updates

    private NavMeshAgent agent;
    private float nextRepath;

    void Awake() => agent = GetComponent<NavMeshAgent>();

    void Update()
    {
        if (target == null || !agent.isOnNavMesh) return;

        // Don't plan a new route every frame: a few times a second is plenty
        if (Time.time >= nextRepath)
        {
            nextRepath = Time.time + repathDelay;
            agent.SetDestination(target.position);
        }

        // Once planning is done, find out whether the target is reachable
        if (!agent.pathPending)
            CanReach = agent.pathStatus == NavMeshPathStatus.PathComplete;
    }

    public bool CanReach { get; private set; }
}

Press Play and move the target around in the Scene view. The character should follow, going through the doorway instead of into walls.

SetDestinationRoute is planned (pathPending)Check pathStatusAgent walks
Planning can take a frame or two, so check pathPending before trusting the result.

Did it arrive? Can it get there?

CheckMeaning
agent.pathPendingStill planning. Wait.
pathStatus == PathCompleteA full route exists.
pathStatus == PathPartialIt can only get close, e.g. the target is in a sealed room.
remainingDistance <= stoppingDistanceArrived (only meaningful once pathPending is false).

Agent settings worth knowing

SettingWhat it does
Speed / AccelerationTop speed and how fast it gets there.
Angular SpeedHow fast it turns.
Stopping DistanceHow close counts as "arrived". Useful for melee range.
Auto BrakingSlow down near the end. Turn off for smooth patrols.

To animate, feed agent.velocity.magnitude into your Animator's speed parameter.

Doors, obstacles and jumps

Troubleshooting

ProblemCheck
"Agent is not on a NavMesh"Did you bake? Is the character standing on the blue area?
Won't go through a doorIs the doorway blue? If not, the agent radius is too big.
Stops shortStopping Distance too high, or the target is off the blue area.
JittersSomething else (Rigidbody, animation, another script) is also moving it.

Common Mistakes

See also