#9870·carla

`FNavigationMesh::Load` and `get_required_files("Nav")` look in different places

Author: M-ColleyCreated Sep 4, 2026Updated Sep 4, 2026

Describe the bug

There are two ways the server can hand a navmesh to a client, and they do not search the same directories.

FNavigationMesh::Load (behind the get_navigation_mesh RPC) checks Saved/Nav/<MapName>.bin first, then content packs, then the content dir:

cpp
const FString SavedFilePath = FPaths::ConvertRelativePathToFull(
    FPaths::ProjectSavedDir() / TEXT("Nav") / FileName);
if (IFileManager::Get().FileExists(*SavedFilePath)) { Files.Add(SavedFilePath); }

But that RPC is not what the client uses. WalkerNavigation's constructor goes through get_required_files("Nav") instead:

cpp
auto files = _simulator.lock()->GetRequiredFiles("Nav");
if (!files.empty()) { _nav.Load(_simulator.lock()->GetCacheFile(files[0], true)); }

and that RPC only consults Saved/ when the map is a generated OpenDRIVE world:

cpp
const bool bGeneratedWorld = Episode->GetMapName().Equals(TEXT("OpenDriveMap"), ...);
...
if (bGeneratedWorld) { /* the only branch that looks at Saved/Nav */ }

For any pre-existing map it searches GameMode->GetFullMapPath() + "/Nav/" and nowhere else.

So the navmesh location documented by the first function is ignored by the path that actually runs. A .bin placed in Saved/Nav/ on a normal map is never loaded, GetRequiredFiles returns empty, _nav is never populated, and every walker call fails — with nothing logged, because an empty file list is not treated as an error.

Steps to reproduce

  1. Take any map that is not OpenDriveMap.
  2. Put a valid navmesh at Saved/Nav/<MapName>.bin.
  3. world.get_random_location_from_navigation()None.
  4. Move the same file to Content/<map folder>/Nav/<MapName>.bin → works.

Expected

One search order, used by both. Saved/ overriding content is a sensible policy — it is what UOpenDrive::FindPathToXODRFile does for the .xodr, so the navmesh reading it only for generated worlds is surprising.

Suggested fix

Drop the bGeneratedWorld gate around the Saved/ lookup in get_required_files so it matches FNavigationMesh::Load (and the .xodr convention), and log when the requested folder yields no files:

cpp
if (Files.IsEmpty())
{
  UE_LOG(LogCarla, Warning,
         TEXT("get_required_files('%s'): nothing found under %s or %s"),
         *Folder, *folderDir, *SavedDir);
}

Environment

  • CARLA ue58-dev-carla @ de3f38e64, running Epic's City Sample