We want to use WPNavmesh in Dynamic Navmesh. Bake Navmesh and allow generation at some point when we want. But when i launch my package i see all the NavMesh I baked before gets rebuilt. I tried several things and when i put some breakpoints i found this :
In FRecastNavMeshGenerator::Init() (RecastNavMeshGenerator.cpp, around line 5519 (in ue5-main branch on github)
The code checks NavSys->IsActiveTilesGenerationEnabled() to decide whether to skip dirtying all navigation bounds. However, this function only checks bGenerateNavigationOnlyAroundNavigationInvokers and does not account for World Partition (bIsWorldPartitioned).
After searching i found this function :
IsUsingActiveTilesGeneration() which covers both cases (invokers OR World Partition).
As a result, in a World Partition project that does not enable Navigation Invokers, IsActiveTilesGenerationEnabled() returns false and the system marks all tiles as dirty at initialization, when i changed this from :
if (NavSys && NavSys->IsActiveTilesGenerationEnabled() == false)
{
MarkNavBoundsDirty();
}
To :
if (NavSys && !DestNavMesh->IsUsingActiveTilesGeneration(*NavSys))
{
MarkNavBoundsDirty();
}
With this change, the pre-built NavMesh data is preserved at initialization and dynamic NavMesh generation only occurs around active tiles.
Tested on UE 5.6.1, bug also visible in ue5-main branch.
[Attachment Removed]
Steps to Reproduce
Reproduction steps (based on our project setup, should be reproducible on any World Partition NavMesh project):
- Create a new project with World Partition enabled
- In Project Settings → Navigation Mesh, set Runtime Generation to Dynamic
- Make sure bGenerateNavigationOnlyAroundNavigationInvokers is disabled (default)
- Place a NavMeshBoundsVolume covering the playable area
- Use the command ai.nav.bNavmeshAllowPartitionedBuildingFromEditor 1
- Build Navigation (Build → Build Paths)
- Verify in editor that NavMesh is correctly baked with NavDataChunkActors
- Move NavDataChunkActors to a Runtime Partition Grid (so they stream with World Partition cells)
- Package the project in Development
- Launch the packaged build
- Observe that all previously baked NavMesh is rebuilt at initialization : MarkNavBoundsDirty() is called on all tiles because IsActiveTilesGenerationEnabled() returns false.
[Attachment Removed]
Do you see the rebuild if the nav data chunk actors are left in the main grid after building WP navmesh? I think the issue arises from moving them out of that grid. If you debug inside of the Init function where it checks for DestNavMesh->HasValidNavmesh, are the data chunk actors spawned yet? Do you see anything printed in the logs for LogNavigation or LogNavigationDirtyArea?
-James
[Attachment Removed]
Sorry the tests took a while, but here is what I have
I did the test you wanted, and with the debugger I don’t go inside this :
if (Config.MaxPolysPerTile <= 0 && DestNavMesh->HasValidNavmesh())
{
const dtNavMeshParams* SavedNavParams = DestNavMesh->GetRecastNavMeshImpl()->DetourNavMesh->getParams();
if (SavedNavParams)
{
Config.MaxPolysPerTile = SavedNavParams->maxPolys;
}
}
Config.MaxPolysPerTile = -1
For LogNavigation and LogNavigationDirtyArea i see no logs.
I tested it with my fix :
if (NavSys && !DestNavMesh->IsUsingActiveTilesGeneration(*NavSys))
{
MarkNavBoundsDirty();
}
So the result is the same, i don’t have rebuild at init
[Attachment Removed]
I believe we have fixed this issue of the rebuild when PIE for dynamic WP navmesh. I am not seeing it using the latest on Main, but I am using the default setup which does not move the nav data chunks to a different grid. I believe there are a couple CLs you may need that fixed a race for registering nav data in the level. The two CLs are:
- CL 51013969
- Fix reentrance in RegisterNavData
- CL 51174146
- Don’t spawn missing navigation data that is already pending for registration
-James
[Attachment Removed]