[UNavModifierComponent] Issue with SetAreaClass at runtime

Hello,

I’m currently investigating possibilities with the UNavigationSystemV1 and I noticed strange behavior with UNavModifierComponent.

I made an example in order to have a simple situation to reproduce.

I have a simple Actor, in a level where there is generated navmesh, on which I put a Box collision set to BlockAll and a UNavModifierComponent.

In my first example, the box collision is close enough to the ground to patch the navmesh and make a hole in it.

In the second example, I set the box collision a little bit more farther from the navmesh on Z axis, to prevent it to make a hole in the navmesh.

In each case, I set first by default in my actor’s NavModifierComponent the AreaClass to UNavArea_Default then OnBeginPlay I switch it to UNavArea_Null and vice versa (default UNavArea_Null then OnBeginPlay UNavArea_Default)

You can notice that in my first example, the navmesh act as expected as the tile present on my box collision is set on/off depending of the context.

But in the second example, as my box collision is not patching the navmesh anymore, you can notice that if my AreaClass is UNavData_Null by default, even if I set back to UNavArea_Default OnBeginPlay, navmesh tile on the box collision won’t be built/displayed.

Is this intended or something that you also noticed on your side ?

Thanks !

SecondExample_BoxCollisionFarFromGround.png(138 KB)
FirstExample_BoxCollisionCloseToGround.png(180 KB)

Hi there,

​Thank you for your report.

What you’re experiencing is intended behavior in UE and is related to the navmesh tile generation logic.

The key difference between the two test cases is:

Default → Null

This modifies an already existing navmesh tile. Since the tile has already been generated, its area classification can be updated accordingly.

Null → Default

If the area is significantly above the Nav Agent’s height and mark as non-walkable area, Recast treats it as irrelevant and does not generate a tile for it. When changing it back to Default, the system would need to create a tile that was never generated in the first place.

However, in Recast, a tile will not be created simply because an area modifier changes its state to “walkable.” Tile generation requires either geometry contribution or explicit dirty marking to trigger a rebuild.

Additionally, ensure that Runtime Generation is set to Dynamic. Without dynamic runtime rebuild enabled, area changes at runtime may not trigger tile regeneration.

You may also try using the RebuildNavigation command to force a navmesh rebuild in this case.

I hope this clarifies the behavior. Please let me know if you have any further questions.

Best regards,

Henry Liu

Hello !

Thanks for the reply.

I thought that the tile was generated even if there is a NavModifier with Null at this location as NavModifiers can be toggled/updated at runtime.

I actually have a collision where navmesh can be built and the runtime generation is also set to Dynamic.

From what I understood in your message, if I need the behavior that “doesn’t work” in my screenshot, I should let the NavModifier to Default then turn it to Null OnBeginPlay but not save it to Null as the NavMesh won’t be generated at all at this place, even if runtime generation is set to Dynamic and the NaVModifier set it back to Default at runtime, right ?

Anyway, I’m not blocked by this situation for now, so it was more to know how it works on the Recast side.

Thanks !

Thank you for the update.

Yes, your understanding is correct. A proper way to set up NavModifier is to first consider the use case. If the mesh is needed for navigation, use Default. This allows the mesh to contribute to the NavMesh, while still providing the flexibility to switch it to Null at runtime under certain conditions, even in the first frame.

If the mesh is not required for navigation, use Null. In some cases, this is an intentional optimisation step that excludes unnecessary geometry from the NavMesh.

Cheers,