reckfellENGINE

Navigation layers: numbers and masks

Filter region access without off-by-one bit errors.

On this page

Navigation layers filter which regions a path query may use. They do not create a passage, disable physics collisions or define character clearance. Different character sizes need suitable navigation geometry, rather than only different masks.

Layer number versus mask

Interface layers are numbered 1–32. The C# NavigationLayers property is a uint; one layer is 1u << (number - 1).

Selected layersMask
11
22
48
1 and 49
None0

Do not use layer number 4 as a mask: the value 4 selects layer 3. Shifting 1u << 4 selects layer 5. Use unsigned 1u for the highest bit and reject invalid numbers before shifting.

Save NavigationLayers.cs in a Reckfell 1.0.0 C# project:

C#
using System;

public static class NavigationLayers
{
    public static uint Bit(int layerNumber)
    {
        if (layerNumber < 1 || layerNumber > 32)
            throw new ArgumentOutOfRangeException(nameof(layerNumber));
        return 1u << (layerNumber - 1);
    }

    public static uint Enable(uint mask, int layerNumber) => mask | Bit(layerNumber);
    public static uint Disable(uint mask, int layerNumber) => mask & ~Bit(layerNumber);
    public static bool Contains(uint mask, int layerNumber) => (mask & Bit(layerNumber)) != 0;
}

Enable(1, 4) returns 9; Disable(9, 1) returns 8. Updating an existing mask preserves its other bits. NavigationRegion2D/3D and NavigationAgent2D/3D also provide SetNavigationLayerValue(number, enabled), which accepts a layer number rather than a mask.

Configure access

  1. Prepare connected navigation regions with existing polygons/meshes. They must belong to the same map and have connected geometry.
  2. Give the first region layer 1 and the second layer 2. A region mask describes membership; a query mask selects allowed layers.
  3. Set query NavigationLayers = 3 to allow both regions, or 1 to allow only the first. A region is eligible when (regionMask & queryMask) != 0.
  4. After region changes, wait for the updated map to be published. Changing only the next query mask does not require rebuilding geometry.
  5. Check the returned endpoint, rather than only whether points exist: with mask 1, a route towards the second region may stop at the first region boundary.

In the adjacent-rectangle fixture, mask 3 connects the start and target. Mask 1 produces a nonempty partial path, while mask 0 admits no region. This was checked separately in 2D and 3D.

When changes become visible

A query mask change applies to its next execution. Region changes pass through NavigationServer synchronization. A new map with MapGetIterationId(map) == 0 is not ready for queries. A nonzero ID establishes that a version has been published, but does not prove that newly submitted changes are included. Waiting exactly one frame is not a universal readiness guarantee.

See path query objects for a query that checks both endpoints.

Diagnose incorrect paths

  • Masks overlap but no passage exists: check map assignment, boundaries and navigation region connections.
  • A character crosses a physical wall: navigation layers do not replace physics; align navigation geometry with collisions and movement.
  • A path exists but does not reach the target: an endpoint was projected onto an allowed surface, or the route is partial.
  • A changed region still returns the old result: wait for the updated map version and issue a new query.

Executed checks cover layer numbers 1/4/32, preservation of other bits, rejection of 0/33, masks and partial paths in 2D/3D, and a 2D region-mask change after synchronization. Baking, editor UI, NavigationLink, agent movement and avoidance are outside this example's coverage.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.