Navmeshes from streaming levels are not loaded if Persistent level has no Nav Bounds Volumes

When using world composition, the only map that loads if you load the persistent map is the persistent map.
I have nothing in my persistent map save for a directional light and some clouds.
All the actual geometry is in my streaming levels for world composition.
So, my persistent level has no Nav bounds Volumes in it.

I wanted the navmesh for each streaming level to be loaded/unloaded with it, so i put the Nav Bounds Volumes into each of the streaming levels themselves.
Once the blank persistent level is loaded, i go to the levels browser, select all the streaming levels, and right click->load them so that they show up.
You need to have Automatic Build Navigation set to OFF to notice this, otherwise it will just rebuild navigation every load anyway (won’t care about NavMeshDataChunks inside the streaming levels themselves)
So i build ALL LEVELs, which makes the green navigation show up over the entire world.
Restart the editor, or create a new map and then discard it and reload the persistent level again.
If you right click and load all the streaming levels again, you will notice that there’s no navigation data on them untill you build it again (even though it saved properly, and there are RecastNavMeshDataChunks being serialized on streaming level load)

This is because, when the persistent map was loaded, void UNavigationSystem::OnWorldInitDone was called, which has a IsThereAnywhereToBuildNavigation() check, and if there are no Nav Bounds Volumes, it DESTROYS all the NavigationData actors. This is a problem later on when any streaming level is loaded, because for it’s tiles to be AttachTo’d to the existing navmesh, OnStreamingLevelAdded must be called on an EXISTING NavData in the NavDataSet array in UNavigationSystem::OnLevelAddedToWorld. Since the NavData was previously destroyed, nothing happens and the tiles from the streaming levels are not added.

I worked around this by just making sure that first branch in OnWorldInitDone is never entered (just commented out IsThereAnywhereToBuildNavigation() == ), but not sure what the proper fix would be, nor why does the NavigationData need to be destroyed if there are no NavBoundsVolumes.

1 Like

Yeah, it’s a known problem with navigation streaming. We usually workaround it by placing any navigation volume in the persistent level, to make IsThereAnywhereToBuildNavigation() happy.

Earlier you could override IsThereAnywhereToBuildNavigation() by setting bWholeWorldNavigable to true, but they removed the UPROPERTY on that.

bWholeWorldNavigable
It’s a deprecated property, and will be probably removed soon.

We will look into fixing UNavigationSystem behavior with world composition. NavigationSystem tries to be very helpful to the user and deletes navmesh actors when there is no bounds in the currently loaded world. Probably more correct behavior would be to let user delete navmesh if he does not need it anymore.

Any update on this? I’m using 4.23.0 now and it still forces to rebuils all the navmesh with any actions with world composition (e.g. if I just load/unload sublevels, or just re-save with no changes – the engine asks to rebuild navmesh).

Bumping this thread, as we’re having the same issue!

bump again

bump

Still an issue in Unreal 5.2 As suggested putting a navigation volume in persistent level would skip the trigger that destroy navigation data.