Hello,
We’ve noticed a bug with setting of NavAreas when navmesh is getting streamed in on World Partitioned Maps. We have doors which store its open/closed state and will set the navmesh polys under it accordingly with the NavModifierComponent. We typically do this on BeginPlay. When we start in the area of the level with the door and the navmesh when the World is created/from a saved game, the Door properly applies the NavArea. However, we when start at a save point that is far away from the door, and we eventually get to the door when before the navmesh and door stream in, the NavArea doesn’t get applied.
I’ve debugged it and have narrowed it down to the Area getting thrown out in FNavigationDirtyAreasController::AddAreas():
`if (bUseWorldPartitionedDynamicMode)
{
// Both conditions must be true to ignore dirtiness.
// If it’s only a visibility change and it’s not in the base navmesh, it’s the case created by loading a data layer (dirtiness must be applied)
// If there is no visibility change, the change is not from loading/unloading a cell (dirtiness must be applied)
// ElementProviderFunc() is not always providing a valid element.
if (const bool bIsFromVisibilityChange = (DirtyElement && DirtyElement->bIsFromVisibilityChange) || (SourceElement && SourceElement->IsFromLevelVisibilityChange()))
{
// If the area is from the addition or removal of elements caused by level loading/unloading and it’s already in the base navmesh ignore the dirtiness.
if (const bool bIsIncludedInBaseNavmesh = (DirtyElement && DirtyElement->bIsInBaseNavmesh) || (SourceElement && SourceElement->IsInBaseNavigationData()))
{
UE_LOG(LogNavigationDirtyArea, VeryVerbose, TEXT(“Ignoring dirtyness (visibility changed and in base navmesh). (element: %s from: %s)”),
*GetFullNameSafe(SourceElement.Get()), *DebugReason.ToString());
return;
}
}
}`
Because it’s from a visibility change and is part of the Base Navmesh, it gets thrown out.
I did a temp fix by delaying the setting of the area a couple frames and this fixes the problem. However, I would not like to rely on the delay hack to fix this issue. Any suggestions on a fix for this? Thank you.
Steps to Reproduce
1) Set a NavArea (we used a NavmodiferComponent) on BeginPlay
2) Be on a World Partitioned Map
3) Start in a location that doesn’t have the Actor that sets the NavArea
4) Move to area in which the Navmesh gets streamed in that the ModifierComponent affects
5) As it streams in, notice that the NavModifier will NOT affect the navmesh that just streamed in
Hi there,
This is intended bahavior on Epics part, in order to prevent uneccessary navigation updates during level streaming. Fortunately there is a nicer way to do your navigation modifier setup, other than using an arbitrary delay.
What I would suggest is to hook into the OnLevelShown delegate to setup your nav modifier. This delegate only fires after everything in the streaming level (in this case the world partition region being streamed in) has finished being added to the world. This means that all components have been registered, and all begin plays have been run, for all actors / components in the streaming level. When the delegate fires, the streaming level is then considered visible, and the bIsFromVisibilityChange flag set to false. It’s not obvious how to get the streaming level associated with the actor being loaded in a world partition setup however, so I’m showing an example of how to do this below.
In Blueprint:
[Image Removed]
In C++:
CustomStreamingFunctionLibrary.h
UCLASS()
class <PROJECT_NAME>_API UCustomStreamingFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, BlueprintPure, Category = “Streaming”, meta = (DefaultToSelf = “Target”))
static ULevelStreaming* GetStreamingLevelFromActor(const AActor* Target);
};
CustomStreamingFunctionLibrary.cpp
ULevelStreaming* UCustomStreamingFunctionLibrary::GetStreamingLevelFromActor(const AActor* Target)
{
return UGameplayStatics::GetStreamingLevel(Target, Target->GetLevel()->GetOutermost()->GetFName());
}
This setup should give you a nice way to setup your nav modifiers on begin play.
Regard,
Lance Chaney
Thank you Lance, that was the event I was looking for. Have tested it and it seems to have worked. Thank you for your help!
Your welcome. Could you mark the answer as best so I can close out the case.
Thanks,
Lance Chaney