๐งญ Lesson 6.1: The NavMesh โ Baking & Agents
You know how to animate a character and move it with the new Input System. But how does an enemy figure out its own way across a level โ around walls, over ramps, without walking off a ledge? Unity's answer is the NavMesh: a pre-computed map of everywhere an agent can legally stand. In this lesson you'll install the AI Navigation package, bake your first NavMesh, and drop in a NavMeshAgent that already knows the terrain.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Explain what a NavMesh is and why games pre-bake navigation
- Install the AI Navigation package from the Package Manager
- Add a NavMeshSurface component and bake a walkable mesh
- Mark geometry as walkable or non-walkable so the bake matches your level
- Configure a NavMeshAgent's speed, angular speed, stopping distance, radius, and height
Estimated Time: 40 minutes ยท Prerequisite: Lesson 5.4 (JSON Save/Load) and comfort placing 3D objects in a scene
In This Lesson
What Is a NavMesh?
A navigation mesh (NavMesh) is a simplified map of your level that answers one question: where can a character legally stand and walk? Unity analyzes your level geometry โ floors, ramps, platforms โ and produces a thin polygon skin that hugs every walkable surface, automatically carving out holes around walls, pits, and obstacles.
Once that map exists, an agent doesn't have to reason about your actual meshes at all. You just say "go there," and Unity finds the shortest legal path across the NavMesh, steering around obstacles for you. This is exactly how enemies, NPCs, and companions get around in most 3D games.
๐ Definition
NavMesh: a baked, walkable surface computed from your level's geometry. It stores where an agent of a given size can stand and how those areas connect, so pathfinding becomes a fast lookup instead of a per-frame analysis of raw meshes.
The word bake matters. Computing the NavMesh is relatively expensive, so you do it once in the Editor and save the result as data. At runtime the agents just read that data โ cheap and instant. It's the same idea as baked lightmaps: pay the cost at author time, reap the speed at play time.
Installing AI Navigation
In older Unity versions navigation lived in a built-in Navigation window and baked a single scene-wide mesh. Unity 6 moves this into a proper package, AI Navigation, built around a component you place in the scene: the NavMeshSurface. It is more flexible (multiple surfaces, per-object control, runtime rebaking) and it's the workflow you should learn.
- Open Window โธ Package Manager.
- Set the source dropdown (top-left) to Unity Registry.
- Search for AI Navigation and click Install.
After it installs you'll have the NavMeshSurface, NavMeshModifier, and NavMeshLink components available, plus the UnityEngine.AI runtime namespace you'll use in code (NavMeshAgent ships with the engine, but the baking components come from this package).
โ ๏ธ The old Navigation window is legacy
You may still find tutorials that say "open Window โธ AI โธ Navigation and click Bake on the Object tab." That's the pre-package workflow. In Unity 6 the recommended path is the NavMeshSurface component. Prefer it โ it's the one that scales to real projects.
The NavMeshSurface Component
A NavMeshSurface is the thing that does the baking. You add it to a GameObject (commonly an empty one named Navigation at the scene root, or your ground object), configure a few settings, and press Bake. Here's the component recreated from its Inspector:
The key settings on the surface:
- Agent Type โ which agent size this mesh is baked for. The default Humanoid has a radius and height; the bake carves the mesh so an agent of that size fits. (You can define extra types in Window โธ AI โธ Navigation (Bake) for, say, a large ogre vs. a small rat.)
- Collect Objects โ All bakes every renderer in the scene; Children limits it to this object's hierarchy; Volume bakes only inside a box you define.
- Include Layers โ a layer mask so you can exclude things (props, triggers) from ever being considered.
- Use Geometry โ bake from Render Meshes (what you see) or Physics Colliders (often cleaner and cheaper).
Marking Geometry
By default the surface treats everything it collects as Walkable. But real levels need nuance: a lava pit should be Not Walkable, a bridge might be a special area, and a decorative rock shouldn't block a path. You control this per-object with the NavMeshModifier component.
Add a NavMeshModifier to any object and you can:
- Override Area โ set that object's surface to Walkable, Not Walkable, or a custom area type (areas carry a movement cost, so you can make agents prefer roads over mud).
- Ignore From Build โ exclude the object entirely, as if it weren't there for navigation.
A common pattern: put your ground and static level meshes on a Ground or Environment layer, restrict the surface's Include Layers to those, and add a NavMeshModifier set to Not Walkable on hazards. That keeps agents on solid, safe ground.
โ Pro Tip
Baking from Physics Colliders instead of Render Meshes is usually the smart default. Your visible mesh might have thousands of triangles for detail an agent never cares about; the box or capsule collider that approximates it bakes faster and gives a cleaner, less jagged NavMesh.
Baking & Reading the Result
With the surface configured, press Bake. Unity computes the mesh and shows it as a translucent blue overlay laid over every walkable surface in the Scene view. Study that overlay carefully โ it is the ground truth of where your agents can go. If the blue doesn't reach a platform, no agent will ever path there.
Here's a top-down view of a small room after baking. Notice how the walkable blue hugs the floor but pulls away from walls and carves a hole around each obstacle:
๐ก The margin is the agent radius. Notice the blue never touches a wall โ it stops one radius short. That's because the NavMesh represents where the agent's center can be while its body still clears the geometry. Bake for a bigger radius and the walkable area shrinks; corridors that were passable can close off entirely.
If your NavMesh looks wrong, the usual culprits are: geometry not marked static or not on an included layer, a slope steeper than the Max Slope setting (agents refuse steep ramps), or a step height taller than Step Height (agents can't climb it). Re-bake after every layout change โ the mesh is a snapshot, not live.
The NavMeshAgent
The mesh is the map; the NavMeshAgent is the traveler. Add the component (Add Component โธ Navigation โธ Nav Mesh Agent) to the GameObject you want to move โ an enemy, an NPC, even the player if you're making a point-and-click game. From now on, moving that object is a matter of telling the agent where, not how.
The settings you'll tune most (all visible in Figure 1):
- Speed โ top movement speed in metres per second.
3.5is a natural walk; bump it up for a sprinting enemy. - Angular Speed โ how fast the agent turns, in degrees per second. Low values make lumbering giants; high values make twitchy insects.
- Acceleration โ how quickly it reaches top speed. Low acceleration gives weighty, momentum-heavy movement.
- Stopping Distance โ how far from the destination the agent halts. Set this to your attack range so a chasing enemy stops at the player rather than trying to stand inside them.
- Radius & Height โ the agent's physical size for avoidance. These should roughly match the character's capsule; they also affect which baked mesh the agent fits on.
Crucially, the agent moves the Transform itself. You do not add a Rigidbody and push it, and you don't write your own movement in Update. The agent reads the NavMesh and drives the position and rotation for you. Here's the smallest possible script that confirms an agent is present and ready:
using UnityEngine;
using UnityEngine.AI; // NavMeshAgent lives here
[RequireComponent(typeof(NavMeshAgent))]
public class AgentProbe : MonoBehaviour
{
NavMeshAgent agent;
void Awake()
{
agent = GetComponent<NavMeshAgent>();
}
void Start()
{
// isOnNavMesh is true only if the agent spawned on top of baked mesh.
if (!agent.isOnNavMesh)
Debug.LogWarning($"{name} is not on a NavMesh โ did you bake, and is it standing on blue?");
else
Debug.Log($"{name} ready. Speed {agent.speed}, stopping at {agent.stoppingDistance}m.");
}
}
โ ๏ธ "SetDestination can only be called on an active agent that is on a NavMesh"
This is the error you'll hit most. It means the agent's spawn position isn't over baked (blue) mesh โ it's floating above it, below it, or off the edge. Fix it by making sure the object sits on the walkable area at scene start, or snap it with NavMesh.SamplePosition. We'll actually give the agent somewhere to go in the next lesson.
Hands-on Challenge
๐๏ธ Exercise 1: Bake a room and drop an agent
Objective: Get a valid NavMesh and a ready agent standing on it.
- Install AI Navigation from the Package Manager.
- Build a simple room: a large ground Plane, four Cube walls, and two or three cubes/cylinders in the middle as obstacles.
- Create an empty GameObject named
Navigation, add a NavMeshSurface, set Collect Objects to All, and press Bake. - Confirm the blue overlay covers the floor and carves holes around your obstacles.
- Add a Capsule, place it on the floor, add a NavMeshAgent, and attach the
AgentProbescript. Press Play and read the Console.
๐ก Hint: no blue appears after baking
Make sure your ground and walls are actually collected โ if Collect Objects is set to Children, the surface only bakes objects parented under the Navigation object. Switch it to All, or parent your geometry under it. Also check the floor isn't tilted past Max Slope.
โ Success check
The Console prints "โฆready. Speed 3.5โฆ" (not the warning), and in the Scene view your capsule sits inside the blue area. You now have a baked map and an agent that knows it's on it.
๐๏ธ Exercise 2: Shrink a doorway
Move two wall cubes close together to form a narrow doorway, then re-bake. Watch the blue: at some gap width the NavMesh stops passing through, because an agent of that radius no longer fits. Now lower the surface's Agent radius (via a custom Agent Type), re-bake, and confirm the passage reopens. This makes the radius-margin idea from Figure 2 concrete.
๐ฏ Quick Quiz
Question 1: Why does Unity bake the NavMesh in the Editor instead of computing it every frame?
Question 2: Your enemy should stop just short of the player to attack rather than shoving into them. Which NavMeshAgent setting handles that?
Question 3: In the top-down bake (Figure 2), why does the blue walkable area never touch the walls?
Summary
๐ Key Takeaways
- A NavMesh is a baked map of everywhere an agent can legally stand; pathfinding reads it instead of your raw meshes.
- Unity 6 navigation lives in the AI Navigation package; you bake with a NavMeshSurface component, not the legacy window.
- Collect Objects, Include Layers, and Use Geometry decide what gets baked; a NavMeshModifier marks per-object walkable / not-walkable / custom areas.
- The walkable mesh is inset by one agent radius โ that's why the blue pulls away from walls and obstacles.
- A NavMeshAgent (Speed, Angular Speed, Acceleration, Stopping Distance, Radius, Height) moves the Transform for you along the mesh.
- Re-bake after every layout change, and make sure agents spawn on the blue or you'll hit the "not on a NavMesh" error.
๐ What's Next?
You have a map and a traveler that knows it's standing on it โ but it hasn't gone anywhere yet. In Lesson 6.2: Moving Agents โ Destinations & Patrol Routes you'll call SetDestination, detect when the agent has arrived, and wire up a patrol that walks a loop of waypoints.
๐งญ Your level now has a brain-map
Bake the surface, drop an agent, confirm it's on the blue. Everything the rest of this module does โ patrols, chasing, guarding โ rides on top of the NavMesh you just built.