Files
UnrealEngineUWP/Engine/Source/Runtime/NavigationSystem/Private/NavSystemConfigOverride.cpp
guillaume guay cc57ba02c6 - Moved the work done in ProcessPendingNavigation from a Task to be triggered via the navigation system tick, after the other required actors were processed such as navigation bound volumes and that the owning level of the navigation data is full loaded.
- Added a call to ConditionalPopulateNavOctree to fix navigation not being regenerated when adding a level with some navigation data to a current world that didn't have one.
- Renamed boolean to better names
- MarkPendingKill the navigation instance when no compatible nav bound for it in the navigation system insead of in the nav mesh generator (except for the abstract nav data)

#rnx
#cr maxime.mercier

Merging manually CL 7842753 using //Release-10.30 to //Main


#ROBOMERGE-SOURCE: CL 7881604 via CL 7914626
#ROBOMERGE-BOT: (v389-7813075)

[CL 7914819 by guillaume guay in Main branch]
2019-08-08 23:32:33 -04:00

173 lines
4.8 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "NavSystemConfigOverride.h"
#include "Engine/World.h"
#include "GameFramework/WorldSettings.h"
#include "AI/NavigationSystemBase.h"
#include "NavigationSystem.h"
#include "TimerManager.h"
#if WITH_EDITORONLY_DATA
#include "UObject/ConstructorHelpers.h"
#include "Components/BillboardComponent.h"
#include "Engine/Texture2D.h"
#include "Editor.h"
#endif // WITH_EDITORONLY_DATA
ANavSystemConfigOverride::ANavSystemConfigOverride(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
USceneComponent* SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComp"));
RootComponent = SceneComponent;
RootComponent->Mobility = EComponentMobility::Static;
#if WITH_EDITORONLY_DATA
SpriteComponent = CreateEditorOnlyDefaultSubobject<UBillboardComponent>(TEXT("Sprite"));
if (!IsRunningCommandlet())
{
// Structure to hold one-time initialization
struct FConstructorStatics
{
ConstructorHelpers::FObjectFinderOptional<UTexture2D> NoteTextureObject;
FName ID_Notes;
FText NAME_Notes;
FConstructorStatics()
: NoteTextureObject(TEXT("/Engine/EditorResources/S_Note"))
, ID_Notes(TEXT("Notes"))
, NAME_Notes(NSLOCTEXT("SpriteCategory", "Notes", "Notes"))
{
}
};
static FConstructorStatics ConstructorStatics;
if (SpriteComponent)
{
SpriteComponent->Sprite = ConstructorStatics.NoteTextureObject.Get();
SpriteComponent->RelativeScale3D = FVector(0.5f, 0.5f, 0.5f);
SpriteComponent->SpriteInfo.Category = ConstructorStatics.ID_Notes;
SpriteComponent->SpriteInfo.DisplayName = ConstructorStatics.NAME_Notes;
SpriteComponent->SetupAttachment(RootComponent);
SpriteComponent->Mobility = EComponentMobility::Static;
}
}
#endif // WITH_EDITORONLY_DATA
bHidden = true;
bCanBeDamaged = false;
bNetLoadOnClient = false;
}
void ANavSystemConfigOverride::PostLoad()
{
Super::PostLoad();
UWorld* World = GetWorld();
if (World != nullptr)
{
if (World->bInTick)
{
World->GetTimerManager().SetTimerForNextTick(this, &ANavSystemConfigOverride::ApplyConfig);
}
else
{
ApplyConfig();
}
}
}
void ANavSystemConfigOverride::ApplyConfig()
{
UWorld* World = GetWorld();
if (World && NavigationSystemConfig)
{
AWorldSettings* WorldSetting = World->GetWorldSettings();
if (WorldSetting)
{
WorldSetting->SetNavigationSystemConfigOverride(NavigationSystemConfig);
}
if (World->bIsWorldInitialized
&& NavigationSystemConfig
#if WITH_EDITOR
&& (GIsEditorLoadingPackage == false || World->IsGameWorld())
#endif // WITH_EDITOR
)
{
UNavigationSystemV1* PrevNavSys = Cast<UNavigationSystemV1>(World->GetNavigationSystem());
World->SetNavigationSystem(nullptr);
const FNavigationSystemRunMode RunMode = World->WorldType == EWorldType::Editor
? FNavigationSystemRunMode::EditorMode
: (World->WorldType == EWorldType::PIE
? FNavigationSystemRunMode::PIEMode
: FNavigationSystemRunMode::GameMode)
;
if (RunMode == FNavigationSystemRunMode::EditorMode)
{
FNavigationSystem::AddNavigationSystemToWorld(*World, RunMode, NavigationSystemConfig, /*bInitializeForWorld=*/false);
#if WITH_EDITOR
UNavigationSystemBase* NewNavSys = World->GetNavigationSystem();
if (NewNavSys)
{
GEditor->GetTimerManager()->SetTimerForNextTick(FTimerDelegate::CreateUObject(this
, &ANavSystemConfigOverride::InitializeForWorld, NewNavSys, World, RunMode));
}
#endif // WITH_EDITOR
}
else
{
FNavigationSystem::AddNavigationSystemToWorld(*World, RunMode, NavigationSystemConfig, /*bInitializeForWorld=*/true);
}
UNavigationSystemV1* NewNavSys = Cast<UNavigationSystemV1>(World->GetNavigationSystem());
if (NewNavSys && PrevNavSys)
{
NewNavSys->FinalizeOverridingNavSystem(*PrevNavSys);
}
}
}
}
void ANavSystemConfigOverride::PostInitProperties()
{
Super::PostInitProperties();
}
#if WITH_EDITOR
void ANavSystemConfigOverride::InitializeForWorld(UNavigationSystemBase* NewNavSys, UWorld* World, const FNavigationSystemRunMode RunMode)
{
if (NewNavSys && World)
{
NewNavSys->InitializeForWorld(*World, RunMode);
}
}
void ANavSystemConfigOverride::ApplyChanges()
{
UWorld* World = GetWorld();
if (World)
{
AWorldSettings* WorldSetting = World->GetWorldSettings();
if (WorldSetting)
{
WorldSetting->SetNavigationSystemConfigOverride(NavigationSystemConfig);
}
// recreate nav sys
World->SetNavigationSystem(nullptr);
FNavigationSystem::AddNavigationSystemToWorld(*World, FNavigationSystemRunMode::EditorMode, NavigationSystemConfig, /*bInitializeForWorld=*/true);
}
}
void ANavSystemConfigOverride::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
bNetLoadOnClient = bLoadOnClient;
}
#endif // WITH_EDITOR