Appearance
NavMesh & AI agents
Galatrix gives NPCs pathfinding so they walk around walls instead of through them — Unity's NavMeshAgent model. You don't draw or bake anything: the engine builds a walkability map from the colliders already in your scene and an agent finds its way with A*. You just decide where each NPC should go (from an AI script); the engine handles how it gets there.
The navmesh is the same in the editor play-test, in published multiplayer, and in a standalone build, so an NPC that behaves in the editor behaves the same when you ship.
Seeing the navmesh in the editor
Open the Editor Settings window and turn on Debug → Show NavMesh.
- The blue surface is the walkable area — where agents can go, with the agent-radius clearance already carved away from walls and props. A cyan outline traces its edge (and the holes punched around obstacles), like Unity's navmesh.
- It shows up while you're editing — no need to press Play. Move, scale, or add an obstacle and the blue area updates so you can see the walkable space change as you build the level.
- Press Play and you also get a green line along each agent's current path.
Turn on Debug → Show Agent Target too and each agent shows a yellow sphere at the point it is currently steering toward — handy for seeing where an NPC thinks it's heading.
TIP
If the blue surface stops short of part of your floor, that area is outside the generated grid — see How the navmesh is built. The grid is sized to your scene's static geometry, so make sure the floor under the agents is a real collider.
How the navmesh is built
It is generated automatically the moment a scene with at least one NavMesh Agent enters Play (and for the edit-mode preview above). There is no bake step and nothing saved to disk — it's rebuilt from the live scene each time.
The mesh is floor-derived: a cell is walkable only where there's actual ground under it, so the navmesh hugs your real floors and gaps / voids / lava pits are never walkable just for being inside the level bounds. What counts as what:
- Floors — flat-ish colliders at least ~2×2 (a ground, a platform, a jump pad) — are the surfaces agents walk on; their footprint becomes walkable.
- Obstacles — everything else solid (walls, crates, pillars) — are carved out of the walkable area, with an agent-radius gap kept clear.
- Ignored — other agents, dynamic and kinematic rigid bodies, animated movers (a sliding door / moving platform — baking it would leave a "ghost wall" where it started), and trigger / water / boundary zones.
So a platform floating in open space is walkable; the empty space around and between platforms is not. Agents also keep an agent-radius clear of ledge edges (drop-offs), not just walls, so they won't walk off into a gap. Rotated walls are matched to their real angled footprint, and clearance is sized to the largest agent in the scene.
WARNING
It's a fast grid over the X/Z plane, not a polygon (recast/detour) navmesh — but it is multi-level: each X/Z column can hold a stack of walkable surfaces at different heights, so a bridge over a path, an overpass, or an upper storey are real, distinct walkable layers. That covers the vast majority of games well; the trade-offs are listed under Limits.
Bake settings (per map)
Scene Settings → NavMesh configures how the grid is generated for this map (Unity's Navigation bake tab). Leave a field blank for auto; with Show NavMesh on you see the blue surface re-bake live as you change them.
| Setting | What it does | Auto default |
|---|---|---|
| Cell Size | Grid resolution (world units per cell). Smaller = finer paths through tight gaps, but more memory. | 1 |
| Agent Radius | Clearance kept from walls. Set it to match your largest agent so big NPCs don't clip. | the largest agent's radius |
| Agent Height | The vertical band around the ground used to decide which colliders block (so overhead geometry is ignored). | 2 |
| Always Bake | Bake even when the scene has no NavMesh Agent — for maps that drive movement entirely from scripts via the nav.* API (custom movement controllers). | off |
These are saved with the map and used identically by the editor, the server, and standalone builds.
Ignore Layers
Scene Settings → NavMesh → Ignore Layers lists your project layers as checkboxes — check one and every object on that layer is left out of the bake entirely: it becomes neither walkable surface nor obstacle, as if it weren't there for navigation. This is Unity's NavMeshSurface Include Layers, inverted.
Use it for decorative clutter agents should walk through (bushes, debris, fences), or a hazard/no-go floor you don't want baked as walkable. Put those objects on their own layer (Inspector → Layer), then check that layer here. With Show NavMesh on, the blue surface updates live as you toggle layers.
Areas & costs
Like Unity's nav areas, you can make some ground cost more (so agents prefer roads, avoid mud) or bar specific agents from it entirely:
- Define areas in Scene Settings → NavMesh → Areas — each has a name and a cost (1 = normal; higher = agents avoid it; e.g. Mud cost 3). Area
0 · Walkable(cost 1) is implicit. - Paint geometry — select a walkable pad/region with a Collider, and set its Nav Area (in the Collider component). That footprint's cells take that area.
- Restrict agents (optional) — a NavMesh Agent's Area Mask lists which areas it may walk on. Uncheck Water on a land NPC and it will never path through water, even if it's the short way. From a script:
agent.setAreaMask(this.entity.id, mask).
Agents take the cheapest route by area cost (and never cut a smoothed shortcut back through a costly or masked area). With Show NavMesh on, costed areas are part of the blue surface.
The NavMesh Agent component
Add Nav Mesh Agent from the Inspector's Add Component menu to make an entity an agent. The component is movement only — it never decides where to go (your script does, below). Key fields:
| Field | Meaning |
|---|---|
| Speed | Top movement speed (units/sec). |
| Acceleration | How fast it speeds up / brakes. |
| Angular Speed | Turn rate (degrees/sec). |
| Stopping Distance | How far from the destination it stops. |
| Radius | The agent's size — its clearance from walls and spacing from other agents. |
| Height | Capsule height — the vertical reach for avoidance (a neighbour farther above/below is treated as on another floor and ignored). |
| Base Offset | How far the agent's origin sits above the floor it walks on, so the mesh lines up with the ground. |
| Auto Braking | Slow down on approach instead of overshooting. Default on. |
| Avoidance Priority | Lower = more important; agents yield to equal-or-higher-priority neighbours. The player is high-priority, so NPCs flow around it. |
| Update Rotation | Engine turns the agent to face travel direction. Turn off to aim it yourself from a script (e.g. strafing while shooting). |
| Pursue Off-Mesh | When the navmesh can't reach the destination, keep going: leave the mesh at the reachable edge and walk straight at the target. Off (default) = stop and wait at the edge, like Unity. See below. |
Ledges, gravity, and Pursue Off-Mesh
Agents follow the floor under them — up ramps and stairs, and down steps. When the ground disappears (they walk off a ledge), they go airborne and fall with the map's gravity until they land on whatever static ground is below. During an off-mesh link jump the arc owns the height instead — gravity never fights a scripted jump.
Pursue Off-Mesh is the relentless-chaser switch. Normally an agent whose target is somewhere the navmesh can't reach — a player standing on an off-mesh rock or a pad the bake eroded away — walks as close as the mesh allows and stops at the edge (Unity's behavior). With Pursue Off-Mesh on, it walks the reachable part of the path, then steps off the navmesh and beelines at the target, falling off ledges on the way if it must. It returns to normal pathfinding by itself as soon as a repath finds the target reachable again. Two things to know:
- Off the mesh there is no obstacle routing — the agent walks straight, so it can bump along walls it would normally path around. Best for open arenas, not mazes.
- A gap it can't clear horizontally is still a gap: it will fall in (and a boundary zone can clean it up). Zombies are not smart. That's the charm.
Driving an agent from a script
The behaviour — chase, patrol, flee — is a normal script. It calls the global agent API, passing the entity's own id, to set a destination; the engine paths and steers there. A minimal chaser:
js
class ChaseAI extends Behaviour {
range = 1.8 // stop and attack within this distance
onUpdate(dt) {
const me = this.entity.id
const player = this.players.getAll()[0]
if (!player) return
const dist = this.math.distance(this.entity.position, player.position)
if (dist <= this.range) {
agent.stop(me) // in range → hold and attack
this.players.damage(player.id, 10 * dt)
} else {
agent.resume(me)
agent.setDestination(me, player.position) // out of range → chase
}
}
}setDestination is safe to call every frame with a moving target — the path only recomputes when the target actually moves. The full surface (stop / resume / resetPath / remainingDistance / setSpeed / warp / calculatePath / isOnNavMesh / …) is in the Script API reference under agent.
Querying the navmesh (no agent)
The nav API answers questions about the walkability grid directly — Unity's static NavMesh.* — for spawn placement, reachability checks, line-of-walk, and the like:
js
// Drop a pickup on the nearest valid spot to a random point, only if it's reachable from spawn.
const target = nav.samplePosition([Math.random() * 40 - 20, 0, Math.random() * 40 - 20])
if (target && nav.calculatePath(this.entity.position, target).status === 'complete') {
this.game.instantiate('coin_prefab', target)
}nav.samplePosition(p)— nearest walkable point top(or null).nav.findClosestEdge(p)— nearest wall edge{ point, distance }.nav.calculatePath(from, to)—{ corners, status, links }without an agent.nav.raycast(from, to)—{ blocked, point }straight-line walkability.nav.isWalkable(p)— is this point on the navmesh.
The grid normally exists only when the scene has an active NavMesh Agent. A scene that uses nav.*without any agent must turn on Scene Settings → NavMesh → Always Bake.
Build your own movement controller (no agent)
The NavMesh Agent gives you Unity's full package — steering, acceleration, avoidance, automatic link jumps. But sometimes the movement itself is the game: a frog that bounds, a ghost that dashes in bursts, a spider that telegraphs before lunging. For that, skip the agent entirely and build the mover as a script on the nav.* query API — the navmesh answers the questions, your script owns every unit of motion. It is the nav analogue of the Custom Vehicle Controller kit.
The recipe:
- Turn on Scene Settings → NavMesh → Always Bake (no agent in the scene means nothing else triggers the bake).
- Give the mover entity no navMeshAgent and no collider — the script poses it directly, and nothing should fight (or bake around) it.
- Each repath interval, ask for the route and walk its corners your way:
js
const r = nav.calculatePath(myGroundPos, targetPos)
// r.corners — world points to visit in order
// r.status — 'complete' | 'partial' (target cut off) | 'invalid' (no route)
// r.links — indices of corners that are off-mesh-link LANDINGS: the segment
// from corners[i-1] into corners[i] is a jump across a gap, not
// walkable ground. Walk the other segments; ARC these.- Land on the real surface with
nav.samplePosition(landingSpot)— it returns the exact ground height, so ramps and steps stay glued.
links is what makes off-mesh links usable from a custom controller: when the next corner's index is in links, don't ground-steer to it — play your own jump (or teleport, or grapple) from the previous corner straight to it, exactly like the engine's auto-jump does for agents.
Custom NavMesh Controller kit (Project → Import Kit) ships all of this working: a hopping chaser whose entire mover is one editable script (HopperController) — fixed-length hop arcs along the corners, a pause between hops, one long arc across the gap link — plus a demo scene with a wall detour, a jump-link gap, and a patrolling target. Change the hop length, the arc, or replace hopping entirely; the route stays correct because the navmesh keeps answering the questions.
Multi-level scenes
Agents follow the ground: walking up a ramp or stairs, the engine samples the floor under the agent and raises/lowers it to match (with a step clamp so it eases over steps and off ledges). Avoidance also respects height — an NPC won't brake for a player standing on a bridge directly overhead.
The navmesh is layered: every walkable surface stacked over the same X/Z becomes its own layer, so a deck over a path gives two walkable levels in that column. A floor with a ceiling closer than the agent height (an overhead deck pressing down on it) is dropped — you can't stand there. Adjacent cells connect only when their heights differ by no more than Max Step (the bake's step/ramp height); a taller drop is a cliff that needs an off-mesh link. So:
- A ramp or stairs joining two levels just works — build it and the agent walks up, level to level (each step ≤ Max Step). See the Bridge Over Path example (
?example=bridge): an NPC climbs a ramp from the ground onto a deck suspended over it. - A ledge to drop, a gap to leap, a doorway — anything not joined by walkable steps — is connected with an off-mesh link (below).
Max Step (Scene Settings → NavMesh) is the tallest height change agents climb between adjacent cells — raise it for chunkier steps, lower it to force more drops through links. It must clear the steepest walkable ramp's per-cell rise (auto ≈ 1.5× cell size).
Off-mesh / jump links
An off-mesh link (Unity's OffMeshLink / NavMeshLink) joins two points that aren't connected by walkable ground — a gap to jump, a ledge to drop off, a doorway between two rooms. Agents route through it like any other connection and auto-traverse with a jump arc; without it those spots are simply unreachable from each other. The agent briefly winds up at the take-off before launching — a beat for a small hop, longer for a big leap — so the jump reads as deliberate and telegraphs to players.
Add NavMesh Link from the Inspector's Add Component menu. The two endpoints are offsets from the entity, so place the entity at the take-off and point the link at the landing:
| Field | Meaning |
|---|---|
| Start / End | The two endpoints, as offsets (X, Y, Z) from the entity's position. The Y of each is the height the agent takes off from / lands at. |
| Bidirectional | Traversable both ways (default). Turn off for a one-way link — a drop you can't climb back up. |
| Cost | A* cost to use the link. Blank = the straight-line distance (a neutral shortcut). Raise it so agents prefer walking around when a ground route exists; lower it to favour the link. |
| Area | Nav area id for masking — an agent whose Area Mask clears this area's bit won't use the link. |
With Show NavMesh on, each link draws as an amber arc between its endpoints (it shows in edit mode too, so you can place it before pressing Play). A script can check agent.isOnOffMeshLink(id) while an agent is mid-jump (Unity NavMeshAgent.isOnOffMeshLink).
TIP
The endpoints snap to the nearest walkable cell, so a link placed at the very lip of a ledge still connects. Keep both ends over (or just beside) real navmesh — a link into the void has nothing to join.
Changing obstacles at runtime
The grid is built once when the scene starts. If a script spawns or destroys an obstacle mid-game (a barricade drops, a wall is blown up), refresh the navmesh so agents account for it:
js
class Barricade extends Behaviour {
drop() {
this.game.instantiate('wall_prefab', this.entity.position)
agent.rebuildNavMesh() // re-bake the grid so NPCs path around the new wall
}
}agent.rebuildNavMesh() rebuilds the grid from the current scene and makes every agent repath. agent.isPathStale(id) returns true for an agent whose route predates the last rebuild (until it recomputes), if you want to react explicitly.
Moving obstacles (NavMesh Obstacle)
For something that moves — a door, an elevator, a patrolling crate — add a NavMesh Obstacle component (Add Component → NavMesh Obstacle) instead of rebuilding. With Carve on it cuts a hole in the navmesh at its current position every frame, so agents path around it as it moves and reclaim the space once it leaves — no script, no rebuild. Set its Size to the footprint to block. (This is Unity's NavMeshObstacle carving.)
Tips
- Doorways / gaps — leave openings a few units wide. Cells default to 1 unit and clearance is kept on both sides, so a too-narrow gap closes off entirely — lower Cell Size (Scene Settings → NavMesh) for tighter spaces.
- Big NPCs — set the agent Radius to match the body so it doesn't clip walls; the grid clears for the largest agent present.
- "NPC stops partway" — usually the destination is off the grid (past the floor) or walled off; turn on Show NavMesh and check the target sits on the blue surface.
- Server vs editor — an agent needs a body to move on the server; the engine gives every agent a kinematic one automatically, so a colliderless NPC that works in the editor also works when published.
Limits (current)
A layered grid, not a polygon navmesh — so it's one shared grid (no separate bakes per agent size), and very fine detail depends on Cell Size. It is multi-level (stacked walkable surfaces per X/Z — bridges, overpasses, upper storeys), with Areas & costs, moving NavMesh Obstacles, and off-mesh / jump links all supported. Show NavMesh draws one translucent sheet per level at its real height.
Try it
Load the NPC demo — three agents (a chaser, a patroller, a wanderer) on one map:
?example=npcdemoOpen Editor Settings → Debug → Show NavMesh + Show Agent Target, then press Play to watch the paths and steering targets update live.