Hello there,
We want to improve our navmesh solution with Recast in our game. Our navmesh is getting very big and hard to generate.
Here is our actual setup:
- We are using WordPartition, and our map is relatively big.
- We are currently using the Recast static navmesh with modifiers. It requires generating a single navmesh that covers the entire map.
- We update our navmesh using a homemade commandlet, similar to what ResavePackage with “BuildNavigationData” does.
Right now, the two main concerns are memory and update time. First, we are currently at nearly 300meg of navigation (from stat llm navigation). That’s a big concern right now, and we didn’t have the whole map yet.
Secondly, the developer’s update. We recently hit the breakpoint where the map cannot be fully loaded due to graphics memory, so they cannot easily build the navmesh locally without closing the editor. They need to push their update without properly testing the navigation and trigger an update by the build machine. I don’t think chunking will help for that.
We are worried about usinghttps://dev.epicgames.com/documentation/unreal-engine/world-partitioned-navigation-meshsince it is still experimental, and the setup seems a bit sketchy (like setting variables in the console). Do you recommend that?
We also ran some tests a while ago with the Dynamic navmesh with nav invoker. It was slow to update and very time-consuming on the game thread. I don’t know if there are recent updates for that.
We are open to trying other navmesh solutions and know how other projects handle this.
Thank you for your advice,
-juju
How large is your map that you are building navmesh for? 25 km^2? Larger? Is the map size so large that even running the ResavePackages commandlet to build navmesh on the dev’s local machine causes OOM issues?
We use a dynamic navmesh with a generated base navmesh to be loaded for FNBR. Our usual process is to build navigation in a nightly build for the map rather than ad-hoc with changes. In Lego FN, we use Nav Invokers with a fully dynamic navmesh.
I know we have made some recent changes to reduce the memory footprint of navmesh tiles by changing to storing vertex locations as float instead of double while making them offsets from the tile center. We have seen some good reductions with this internally while still having tiles to cover LWC. Other ways to reduce navigation memory overhead is to use larger tiles so fewer tile headers are needed. That comes with a trade-off though as larger tiles are more expensive to rebuild at runtime.
WP Navmesh is not something I would really recommend, and that is especially so as you are using Dynamic Modifiers Only generation mode. It has some benefits of allowing to stream in chunks of navmesh at runtime and reduces the overall memory of tiles as you can use a smaller pool of tiles for the world. WP Navmesh though is not quick or easy to build. It requires running a commandlet to build the navmesh for the world and I have heard reports from other licensees that it can take several hours for very large worlds to build. So it does not increase the ability to incrementally test update quickly by designers or developers. There are also issues with streaming in/out nav data chunk actors where they will not be GC’d prior to attempting to load them again resulting in their navmesh tiles not being added. There are some CVars to prevent that, but that same CVar can cause other perf concerns with no longer reusing streamed out actors that have not yet been GC’d.
-James
Hello!
We are currently sitting at 15km X 10km. We are updating navmodifiers frequently, since all characters can activate/deactivate one when stopping/moving to improve character avoidance. I will check if we could increase the tile size to see how it affects the memory footprint.
Another thing we considered is having separate NavDatas loaded individually by the data layer, since we have large sections that don’t require a navmesh, which disconnects NavDatas from each other. The WorldPartition system doesn’t allow this out of the box when testing that. It would be nice to have something like this.
Thank you.
You are correct that we do not support separate nav data in the data layers by default. One issue is that we do not support multiple navmeshes for the same agent size in the engine.
There is another issue we have run into when attempting to allow for separate tile data chunks to be saved in data layers, and that issue is that data layers are not mutually exclusive. What I mean by that is that when you load a nav data chunk actor and it adds its tiles to the navmesh, it will replace the existing tiles with its tile data. Tiles are not merged, and this could end up with multiple active data layers with navigation tiles being active. However, the tiles in game would be whichever tiles were added last to the navmesh. So you could end up with meshes that are not avoided, incorrect modifiers, holes in the navmesh for meshes that are not there, and more troubling scenarios. We did have a PR submitted to us a few versions back for adding support for nav data chunk actors in data layers. It could be looked into, but we have not fully tested nor investigated it ourselves. It would be use as-is, but it will likely need some massaging of the code because it is for an earlier engine version. Here is a link to that specific PR.
With needing some updates for only sections of the map, you may be interested in the Nav Invokers. It allows for navmesh on demand where you truly need it. There is also an experimental feature for invokers where you can load a base navmesh that is baked offline and then use invokers to only update tiles in range. This would allow for limited, dynamic updates where you deem relevant, and the ability to load a base navmesh rather than fully generate one. You might look into WP navmesh as it allows for streaming nav data chunks for the grid cells. WP navmesh is still very limited in support and there are known issues for reusing streamed out levels that have not been GC’d as the nav data chunk actors do not have the tile data reassociated with them. There are some ways around that via CVars to not reuse unloaded levels or to change the tile behavior where the nav data chunk actors retain a copy of the tiles. That second option increases memory overhead as the tiles are essentially duplicated.
Of note for memory for tiles, there was a change made for 5.8 where the tile vertices are saved as floats instead of doubles, and this also changes their data to be stored as an offset from the tile. Seeing roughly 50% memory improvements in FN, but it is not a full 50% as there is other overhead in the tiles beyond vertices.
-James