Navmesh and Level Streaming

Hello there,

I wanted to share the problems we have right now using Navmesh and Level Streaming, and try to find some guidance and solutions.

Our worlds are split in multiple sub levels streamed at runtime using Streaming Volumes. Navigation bounds volumes are placed along with mesh actors and other NavModifiers that affect the NavMesh shape in the same sub levels and streamed at runtime.

Before submitting their work, our designers Build Path, save the sublevels that contain the Nav related actors and submit. Our packaging pipe takes those levels as is and package for PC and consoles.

Our Navmesh generation is set to Dynamic Modifiers Only to not tank the runtime performance and since we use some NavModifiers to locally update the Navmesh along with some dynamic actors that can interact with the player.

Here is a list of Navmesh settings:

  • Tile Pool Size 8196
  • Tile Size UU 500
  • Default Cell settings Size 10 | Height 10 | Step 35
  • Do Fully Async Nav Data Gathering True
  • Force Rebuild on Load True (not sure what this does exactly)

Consistently now on high end PCs and consoles - When loading our persistent worlds and teleporting the player where it should be - We have inconsistent Navmesh generation - Sometimes some tiles are missing, sometimes they are there, sometimes just going back and forth between streaming volumes, the missing tiles finally appear.

Based on the Gameplay Debugger visuals in Dev builds (0: Navmesh submenu)

We don’t have much tools to use to understand the issue, nor any idea what could trigger those tiles to generate or not.

Could you please provide us with some good practice regarding Navmesh generation in a level streaming setup?

When Generating Paths, do we need to resave all the Levels (including Persistent) that contain a NavMesh Volume?

Do we need to generate path before saving and submitting levels?

Is there any offline commandlet we could run on our build machines before packaging the game?

There is plenty of similar topics on the Internet but most of them contradict themselves, some say you should put the NavBounds in the persistent levels, some say NavBounds should be located in sublvels, etc etc. which make it impossible for us to find the right way to build our Navigation stuff.

On top of that we tried to make use of the NavigationSystem API RebuildAll function - But this seems to do nothing at runtime.

Cheers,

Simon

Hi Simon,

From your post, I believe you are using the World Composition streaming (UE4 streaming) rather than the newer World Partition streaming. This would lead to needing some of our older advice for setting up navmesh for sub-levels. We recommend having one large navmesh bounds in the persistent level that covers all possible navigable space including the sub-levels. Your sub-levels should have a navmesh bounds in them that very closely fits the geometry of the level. It could be that the overlapping bounds from sub-levels are removing tiles that are within both bounds when one is unloaded. If you have missing tiles routinely (square holes in the navmesh), you may check the logs to make sure the max tile limit has not been reached. This could certainly happen when streaming in new sub-levels if there are other active sub-levels that have not been unloaded yet.

RebuildAll should work at runtime. In your setup, it would only process dirty areas on the navmesh with your dynamic modifiers only setting. Would you be able to share out the logs or any screenshots/videos of when this is happening in your project?

-James