egametang/ET · critical · Exception

nav load fail: {name}

Error message

nav load fail: {name}

What it means

PathfindingComponent.Awake looks up the named navmesh via NavmeshComponent.Instance.Get(name) and throws if the result is null — i.e. the nav data was never loaded under that name. Get uses dictionary indexing internally, so in practice this fires when Load(name) was never awaited before the component awoke.

Source

Thrown at Packages/cn.etetet.recast/Scripts/Hotfix/Share/PathfindingComponentSystem.cs:22

using DotRecast.Core;
using DotRecast.Detour;
using DotRecast.Detour.Io;
using Unity.Mathematics;

namespace ET
{
    [EntitySystemOf(typeof(PathfindingComponent))]
    public static partial class PathfindingComponentSystem
    {
        [EntitySystem]
        private static void Awake(this PathfindingComponent self, string name)
        {
            self.Name = name;
            self.navMesh = NavmeshComponent.Instance.Get(name);
            
            if (self.navMesh == null)
            {
                throw new Exception($"nav load fail: {name}");
            }
            
            self.filter = new DtQueryDefaultFilter();
            self.query = new DtNavMeshQuery(self.navMesh);
        }

        [EntitySystem]
        private static void Destroy(this PathfindingComponent self)
        {
            self.Name = string.Empty;
            self.navMesh = null;
        }
        
        public static void Find(this PathfindingComponent self, float3 start, float3 target, List<float3> result)
        {
            if (self.navMesh == null)
            {
                Log.Debug("寻路| Find 失败 pathfinding ptr is zero");

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure NavmeshComponent.Instance.Load(mapName) is awaited before any PathfindingComponent using that name is created.
  2. Verify the map name string matches exactly (case, suffix) across load and component construction sites.
  3. Confirm the recast file exists and isn't empty so Load actually populates the dictionary (else error 314 fires first).
  4. If loading is async, gate entity spawning on the load completion (await the Load in scene init).

Example fix

// before: entity spawned before nav loads
entity.AddComponent<PathfindingComponent, string>(mapName);
await NavmeshComponent.Instance.Load(mapName);
// after: load first, then spawn
await NavmeshComponent.Instance.Load(mapName);
entity.AddComponent<PathfindingComponent, string>(mapName);
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing PathfindingComponent, ensure nav data is loaded
await NavmeshComponent.Instance.Load(mapName);
if (NavmeshComponent.Instance.Get(mapName) == null)
    throw new InvalidOperationException($"Navmesh '{mapName}' failed to load; cannot create PathfindingComponent");
entity.AddComponent<PathfindingComponent, string>(mapName);

Prevention

When it happens

Trigger: Constructing a PathfindingComponent with a name for which NavmeshComponent.Instance.navmeshs has no entry, or whose entry is null. Triggered when an entity with a PathfindingComponent is created before NavmeshComponent.Load(name) completes.

Common situations: Forgetting to call NavmeshComponent.Instance.Load(mapName) at server startup before spawning pathfinding-using entities; a typo in the map name; loading the map asynchronously but spawning an NPC before the await returns; map file missing so Load silently produced nothing.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/591f2f52a96aaf1e. Report an issue: GitHub.