For the complete documentation index, see llms.txt. This page is also available as Markdown.

Navmesh & Collision

Navmeshes define walkable space for pathfinding and movement constraints.

Navmeshes define the walkable areas in your world. Use them to:

  • Snap spawned items onto reachable ground

  • Lock players/NPCs to walkable regions

Colliders can also be used to carve navmeshes in the editor.

Components (quick overview)

  • Navmesh: the baked navigation mesh you query and rebuild

  • Navmesh_Loop: polygon loops that define walkable boundaries (and holes)

  • Colliders: Box_Collider, Circle_Collider, Edge_Collider, Polygon_Collider

For movement/pathfinding (Movement_Agent) see Movement Agents/NPCs.

Navmesh :: class : Component {
    // Project a point onto this navmesh.
    // triangle_hint is an acceleration hint you can reuse for nearby queries.
    try_find_closest_point_on_navmesh :: method(
        to_point: v2,
        result: ref v2,
        triangle_hint: ref s64
    ) -> bool;

    // Cast through the navmesh. Returns the endpoint and whether the query succeeded.
    try_raycast :: method(position: v2, direction: v2) -> v2, bool;

    // Queue a rebuild for the normal navmesh update.
    mark_for_rebuild :: method();

    // Rebuild now when a same-frame query needs the new geometry.
    rebuild_immediately :: method() -> bool;

    // Include only colliders on this entity and its descendants.
    child_colliders_only: bool;

    // Detect input changes and rebuild automatically.
    enable_automatic_rebuilds: bool;
}

Editor setup (building a navmesh)

  1. Create an entity and add a Navmesh component.

  2. Create child entities with Navmesh_Loop components to define walkable polygons.

  3. For each Navmesh_Loop:

    • Add points to define the loop shape

    • Order the outer boundary points counter-clockwise

    • Toggle Flip Inside Outside to make a hole/obstacle instead of walkable space

  4. Use the navmesh debug options in the inspector to visualize the triangles.

By default, a Navmesh_Loop defines a walkable area. Flip it to "punch holes" (unwalkable islands) into an existing navmesh.

Colliders and navmesh loops

Colliders can also contribute loops via collider inspector options (for example "Make Navmesh Loop" / "Flip Navmesh Loop").

Important caveats:

  • With Enable Automatic Rebuilds, navmeshes detect loop, collider, tilemap, and child-navmesh input changes and queue a rebuild.

  • Turn on Child Colliders Only to ignore unrelated colliders elsewhere in the scene.

  • With automatic rebuilds disabled, call mark_for_rebuild() after changing an input.

  • Call rebuild_immediately() only before a same-frame query that requires the changed geometry.

Spawning on navmesh (clamp to reachable ground)

Use try_find_closest_point_on_navmesh to project a desired position onto the closest valid point on a navmesh:

Reuse triangle_hint for repeated queries in the same area (loot spawners, wave spawns, etc). It can significantly speed up projection.

Rebuilding navmeshes immediately

Most geometry changes are picked up automatically. Use this only when you need to force timing:

  • rebuild_immediately(): rebuilds now (use only if you must query the updated mesh in the same frame)

Parent navmeshes refresh after child navmeshes, so stitched parent meshes automatically pick up child mesh input changes.

Raycasting across a navmesh

try_raycast follows direction to the navmesh boundary. The second result reports whether the query succeeded.

Collider triggers

A collider with is_trigger == true can report when another collider enters, remains inside, or exits. Trigger callbacks work on stationary and moving colliders; a Movement_Agent is not required.

Proximity checks and custom hit logic

For trigger zones that use range queries instead of collider callbacks, pickups, projectile checks, or other custom hit logic, use:

  • Scene.get_all_components_in_range / Scene.get_closest_component_in_range

  • Simple distance checks (in_range) to decide "inside", "picked up", "hit", etc.

Scene query helpers

Run damage, pickups, and scoring in the normal shared gameplay path. Do not guard predicted gameplay with Game.is_server().

Trigger volume (enter / stay / exit)

To simulate a trigger zone, keep a list of who was inside last frame and diff it against the current frame’s results.

Pickups (closest in range)

Fast movement "hits" (simple sub-stepping)

If you move quickly (dash, projectile), you can miss narrow targets when checking only the final position. A simple workaround is sub-stepping: sample a few points between last and new position and run the same range queries.

Last updated