Hello,
Our project uses world partition and a Dynamic world partitioned Navmesh.
We use data layers to change the state of the level. Some packed level actors in our level such as bridges or obstacles are loaded with a runtime data layer.
However, navmesh tiles including these packed level actors are not dirtied when we load these data layers at runtime.
After some investigation here is what I found, when we load the data layer:
-
Packed Level actors are InstancedStaticMeshComponents that implement by default ‘UInstancedStaticMeshComponent::SupportsPartialNavigationUpdate’ to return true which means that when ‘RegisterComponentWithWorld’ is called on the packed level actor, ‘PartialNavigationUpdates’ is called.
-
This ends up calling ‘FNavigationDataHandler::UpdateNavOctreeElementBounds’. Because the static mesh was in an unloaded data layer previously, it is not a registered element yet , so we search for a pending update in the octree controller (NavigationDataHandler.cpp:488). But no pending updates was added yet so we don’t add the actor’s bounds in the explicit dirty areas, which is supposed to be the pattern when using partial navigation updates.
-
After this, ‘ALevelInstance::PostRegisterAllComponents’ is called which ends up calling ‘FNavigationDataHandler::RegisterElementWithNavOctree’ which adds the navigation element for the actor in pending updates (NavigationDataHandler.cpp:128).
-
Finally, the Navigation System ticks and starts processing the pending updates. ‘FNavigationDataHandler::AddElementToNavOctree’ is called, but because the packed level actor is flagged as supporting partial updates, it also sets bShouldSkipDirtyAreaOnAddOrRemove as true, which means it searches for explicit areas to dirty, but there are none (NavigationDataHandler.cpp:221).
It seems to me that this might be just an ordering issue but I might be wrong.
The problem isn’t noticed when we place directly Level instances in the level, but that’s just because the individual meshes are properly registered when we load the data layer, and that each invidual mesh isn’t flagged as supporting partial navigation updates.
Do you have any idea of a clean solution we could use in our project so that we can keep using packed level actors in data layers and make them work properly with our navmesh ?
Additionally, some of our levels use data layers to a huge extent (almost 70% of the levels can be different after changing the activated layers). What would you recommend when building the navmesh to make sure that it is built properly, and correctly updated when loading or unloading data layers ?
I know that there is not a lot of support for data layers with world partition and navmesh right now but any solution to properly generate and update the navmesh would be awesome.
Thank you for your time,
Sincerely,
Timothé Louzier
Steps to Reproduce
In a World using World Partition and a Dynamic World partitioned NavMesh, place a packed level actor supposed to affect navigation in any unloaded by default data layer.
Build the navmesh with the layer loaded to make sure the base navmesh includes the packed level actor’s navigation data.
At runtime, load the data layer and notice the navmesh isn’t refreshed on the tiles occupied by the packed level actor, and navmesh isn’t refreshed.
Notice we don’t observe the same issue at runtime. Notice also that the issue does not appear on level instances directly placed in the level without using a packed level actor.
Using the included repro project:
Start the PIE, display the navmesh using the apostrophe key and 0 on the numpad, or leave the in game view with F8.
Then press L to toggle the DataLayer’s loading state.
Thank you for the repro project. It does show the PLA being loaded without the navmesh update. I tested around in that level with a couple actors with ISM and HISM components. The ISM component instance affected navigation whenever it was loaded and unloaded, but the HISM would only affect navigation on the first load. I think it may be something with HISM components in general. Was this working for you in previous versions? I know there was some navigation related deprecation changes to HISM, but those changes were to have it behave like ISM in regards to navigation.
-James
Hello,
No I’m not sure this was working in previous versions, but we were not loading or unloading ISM and HISM as intensively before so we might have missed it.
Do you think this issue is limited to HISM ? Because it seems to me that both ISM and HISM have issues with Data Layers
Navigation support for data layers is very rough with minimal support. I mentioned the HISM as I could trigger an issue with a standard HISM component actor similar to what I saw for the PLA. I was answering another user earlier today about an HISM navmesh issue with instances added not correctly updating bounds in 5.6. That was fixed in 5.7 and I will need to update your repro project and test if this is a similar problem or if something else is happening specifically around PLA loading from data layers.
-James
That would be great! We would be very interested to know if these issues are fixed in 5.7 yes, but we won’t be able to switch to it before our next release.
If the issue is fixed we will most likely cherry pick what we need to fix these issues.
Also, do you have any insight on the other issue ?
“Additionally, some of our levels use data layers to a huge extent (almost 70% of the levels can be different after changing the activated layers). What would you recommend when building the navmesh to make sure that it is built properly, and correctly updated when loading or unloading data layers ?”
Thanks in advance
We do not have much support for data layers in WP navmesh. We can include Actors in a data layer with the base navmesh, but we do not have a system to store navmesh data chunks in data layers to be used when the data layer is activated. Doing so also introduces other issues because tiles are not merged when new tiles at the same location are added to the navmesh. It would replace the tile with the newest/most recently loaded nav data chunk. So your data layers would need to be mutually exclusive to not overwrite the others tiles. I know some users have attempted to make data layer navmesh work. I believe we may have an open PR for their work, but it has not been fully investigated on our side and the aforementioned mutual exclusivity also makes it hard to enforce in a general sense in the engine as data layers are not mutually exclusive. Our recommendation for navmesh in WP worlds is actually to use Invokers or a regular dynamic navmesh if possible. Both Lego FN and FNBR use those modes, respectively.
I will also add that we do not have planned work at this time for further WP navmesh development. So I do not expect to see any workflow or functionality changes in the next release.