StaticNavmesh and level streaming

We have a large map with streaming sub-levels and was wondering if it was possible to use a static navmesh. We want to avoid using dynamic navmesh.

Based on this post Static NavMeshes and Level Streaming - Debugging, Optimization, & Profiling - Epic Developer Community Forums
it should be possible.

I’ve attempted to put one NavVolume on the persistent level and expand across the entire map then load the sub-levels and save. No Luck.

I’ve also attempted exactly what ddvlost describes. Placed one one NavMeshBounds in Persistent Level and other volumes in each sub-level. No luck with that either.

Most of the time it only generates a subsection of the navmesh in editor. Sometimes it has really strange behavior. When I load into the level in editor after saving the navmesh it translates all the sublevel navmeshes ontop of eachother and translates them onto a random location.

Any advice on how to setup this properly would be greatly appreciated. Thanks.

Hi, that was my post on the forums.

For navmesh streaming, NavVolumes should be setup as described in second method, place NavVolumes in sub-levels.
Also make sure that Recast actor “Runtime Generation” property set to “Static”. Each NavVolume should be sized to cover geometry in own level, not the whole world. And at least one NavVolume has to be in P-level, even if it does not have any geometry. One thing that can confuse navigation is if there is a Recast actor in the sub-level. Recast actors should be only in P-level. If you see them in other levels, please delete them. Do you use world composition or traditional level streaming? Do you use sub-level transformations? that will not work with Static navmesh.

I see, it could be issue with racast navmesh versioning. When “Build Paths” is executed, it assumes it can completely delete old navmesh (in Persistent level ) and regenerate new one. Recast navmesh most likely has internal version which gets updated when it’s re-created so version of navmesh parts which are stored in unloaded sub-levels does not match with a new navmesh. We will look what should be changed to support this workflow.

We are having the issue with a map/level setup with world composition. The only way that we could get valid nav to show up was having the nav set to dynamic in the recast actor.

We are having a similar issue. We tried the steps above and they didn’t work for us either. In particular:

One thing that can confuse navigation is if there is a Recast actor in the sub-level. Recast actors should be only in P-level. If you see them in other levels, please delete them.

When we delete the Recast actor in our sublevels we seem to be deleting the nav mesh pre-generated for that sublevel. If that’s gone, then what would stream in at runtime?

The only way we’ve had these steps work is by deleting the recast actors in our sub-levels and having the recast actor in the P-Level set to dynamic. Then at runtime, it generates the level. However, this is not desirable since our levels are quite large and navigation can’t be queried when we need it.

There were fixes related to static navmesh streaming. CL# 3589223. Could you integrate it? Also with this fix I would recommend to disable automatic nav-mesh updates in the editor. This option can be found in Editor settings.

Also for static navmesh streaming to work correctly you will need to set “Fixed Tile Size Pool” to true in recast actor and “Pool Size” will be the maximum number of mesh tiles that can present in navigation mesh at any moment.

Navigation mesh is always in P-Level. Sub-levels will cut a number of tiles from navigation mesh and store then inside sub-level package. When sub-level is streamed in those tiles will be attached to navmesh in P-level and detached when streamed out. Number of tiles that will be cut from navmesh depends on area of NavVolumes in the sub-level. If there are no NavVolumes, sub-level will not store any tiles.

To work with static navmesh streaming in the Editor you will need to disable “Update Navigation Automatically” option in the Editor settings. And also will need those fixes in CL# 3589223. And “Fixed Tile Size Pool” settings like described in earlier message.

Thank you for the reply Dmitriy, that clears things up a bit. I can’t confirm how well it works since the nature of our problem is a bit different (the levels we stream in are not sub-levels of the persistent level, but selected at runtime), so it doesn’t seem like we can have the P-Level’s recast actor generate and segment the mesh for us.

For anyone else on this trail, the change Dmitriy referenced is exposed publicly here, as part of a larger commit: https://github.com/EpicGames/UnrealEngine/commit/dc647b9547095baaf2229a240ffbfae91f2a03f2

I integrated that changelist. However, whenever I save the map it seems to completely delete the navmesh and asks to be rebuilt. Is there some other setting or changelist I’m missing?

Thanks.

Hi,

Sorry for delay. I don’t see this behavior in my test cases. Do you have “Update Navigation Automatically” option in editor settings disabled?

It happens when I save all the sub-levels, just for more information not just the main level. I do have “Update Navigation Automatically” disabled though. Are your tests using world composition and world origin rebasing? Also, is it possible there is another change-list that I missed integrating to help resolved this issue? We are on 4.16.2.

I run tests with world composition and origin rebasing enabled. There is an issue with streaming in navmesh when origin is not at zero. It does not appear at correct place. We will work on a fix. But I could not reproduce deleted nav-mesh on saving. Do you see deleted nav-mesh if you have origin rebasing disabled?

We get the same results with either setting for origin rebasing. The navigation will work fine in Standalone, until you close and re-open the level. We can’t get this to work in packaged builds either.

Hi, sorry for delay.

I think I found what is missing. There is was a change in another dev branch that my change relies on. Could you integrate CL# 3461373 along with mine CL# 3589223 ? All those fixes are in 4.18 release.

Hi,
I had the same issue and integrating those two changelists fixed the issue indeed.
However, it seems that it is always necessary to load all the levels and generate the navmesh, even if you just modify one section. Otherwise, if you only load one level, build the navmesh and save that level, its bound will be considered as navmesh edges and will never “stick” with its neighbours once both levels are loaded at runtime.
Is there a way to achieve this result without loading the whole navmesh every time you want to modify a single level? This will help the pipeline even if the results are actually the same.
Thanks

It should work with static nav-mesh. By “never stick” do you mean that path-finding does not work between separately built levels?

Yes, exactly. When building a single streaming level, I need to load all adjacent levels, which means that, assuming they form a grid, if you only modify 1 level, you need to load 10 of them in order to generate and save the navmesh in the single level that has been modified. NPCs won’t be able to navigate smoothly between levels with a single pathfind reguest. It can happen that they navigate to the level limit, and then if another navigation request is done, they can actually find the nearest polygon on the other level and keep moving, but it looks glitchy.
Ideally, if would be nice to only load, modify and generate navmesh on one streaming level, and then that it just works when adjacent levels are loaded.

Sorry for the delay.
Are you using world composition? Otherwise I’m not sure how you load sub-levels one by one in the editor. Also do you use “Fixed Tile Pool Size” property on a recast navmesh actor? This is essential to use if navmesh size in tiles can’t be computed ahead of time. This setting pre-allocates fixed number of tiles in the navmesh, so it does not have to change configuration when nav bounds added or removed from world.

Does sub-levels navmesh “stick” if you don’t use “Build Paths” command and just move a bit nav volume to trigger a build?

Hi,
Yes I use World Composition and also Fixed Tile Pool Size.
If I don’t use Build Paths navmesh does nothing on moving nav volumes because I’ve disabled Update Navigation Automatically on the editor settings, as suggested in this same thread. So I always use Build Paths.
Just to be sure I’ve explained myself: If I load all the levels and then Build Paths, everything will work fine and navmesh sublevels will load/unload and attach/detach to each other. But then if I load a world, I load only one single world composition level, build paths, and save that level, then when playing this level will correctly load its NavMesh but it won’t get attached to the adjacent levels.
This is just an issue in terms of production pipeline: it would be nice to be able to rebuild navmesh on one sub-level without loading all of them.

I see, it could be issue with racast navmesh versioning. When “Build Paths” is executed, it assumes it can completely delete old navmesh (in Persistent level ) and regenerate new one. Recast navmesh most likely has internal version which gets updated when it’s re-created so version of navmesh parts which are stored in unloaded sub-levels does not match with a new navmesh. We will look what should be changed to support this workflow.