Files
Mieszko Zielinski b51e0bbe37 Un-virtualized UNavigationSystemV1::AddDirtyArea before it gets shipped in 4.23 #UE4 #Athena
It wasn't virtual pre-4.23 and was added to accomodate on of the internal project's requirements. I've refactored the project-specific code to not need it.
This change is required in support of the soon-to-come navigation system refactor/extension.

#jira none
#review-6618928 @Yoan.StAmant
#rb Yoan.StAmant

[CL 6628443 by Mieszko Zielinski in Dev-Framework branch]
2019-05-24 07:33:53 -04:00

1054 lines
51 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Templates/SubclassOf.h"
#include "UObject/WeakObjectPtr.h"
#include "Misc/CoreMisc.h"
#include "Misc/CoreDelegates.h"
#include "NavFilters/NavigationQueryFilter.h"
#include "AI/Navigation/NavigationTypes.h"
#include "NavigationSystemTypes.h"
#include "NavigationData.h"
#include "AI/NavigationSystemBase.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "NavigationOctree.h"
#include "AI/NavigationSystemConfig.h"
#include "NavigationSystem.generated.h"
class AController;
class ANavMeshBoundsVolume;
class AWorldSettings;
class FEdMode;
class FNavDataGenerator;
class FNavigationOctree;
class INavLinkCustomInterface;
class INavRelevantInterface;
class UCrowdManagerBase;
class UNavArea;
class UNavigationPath;
class UNavigationSystemModuleConfig;
struct FNavigationRelevantData;
struct FNavigationOctreeElement;
#if WITH_EDITOR
class FEdMode;
#endif // WITH_EDITOR
/** delegate to let interested parties know that new nav area class has been registered */
DECLARE_MULTICAST_DELEGATE_OneParam(FOnNavAreaChanged, const UClass* /*AreaClass*/);
/** Delegate to let interested parties know that Nav Data has been registered */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnNavDataGenericEvent, ANavigationData*, NavData);
DECLARE_MULTICAST_DELEGATE(FOnNavigationInitDone);
namespace NavigationDebugDrawing
{
extern const NAVIGATIONSYSTEM_API float PathLineThickness;
extern const NAVIGATIONSYSTEM_API FVector PathOffset;
extern const NAVIGATIONSYSTEM_API FVector PathNodeBoxExtent;
}
namespace FNavigationSystem
{
/**
* Used to construct an ANavigationData instance for specified navigation data agent
*/
typedef ANavigationData* (*FNavigationDataInstanceCreator)(UWorld*, const FNavDataConfig&);
struct NAVIGATIONSYSTEM_API FCustomLinkOwnerInfo
{
FWeakObjectPtr LinkOwner;
INavLinkCustomInterface* LinkInterface;
FCustomLinkOwnerInfo() : LinkInterface(nullptr) {}
FCustomLinkOwnerInfo(INavLinkCustomInterface* Link);
bool IsValid() const { return LinkOwner.IsValid(); }
};
bool NAVIGATIONSYSTEM_API ShouldLoadNavigationOnClient(ANavigationData& NavData);
bool NAVIGATIONSYSTEM_API ShouldDiscardSubLevelNavData(ANavigationData& NavData);
void NAVIGATIONSYSTEM_API MakeAllComponentsNeverAffectNav(AActor& Actor);
}
struct FNavigationSystemExec: public FSelfRegisteringExec
{
//~ Begin FExec Interface
virtual bool Exec(UWorld* Inworld, const TCHAR* Cmd, FOutputDevice& Ar) override;
//~ End FExec Interface
};
namespace ENavigationBuildLock
{
enum Type
{
NoUpdateInEditor = 1 << 1, // editor doesn't allow automatic updates
InitialLock = 1 << 2, // initial lock, release manually after levels are ready for rebuild (e.g. streaming)
Custom = 1 << 3,
};
}
UCLASS(Within=World, config=Engine, defaultconfig)
class NAVIGATIONSYSTEM_API UNavigationSystemV1 : public UNavigationSystemBase
{
GENERATED_BODY()
friend UNavigationSystemModuleConfig;
public:
UNavigationSystemV1(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
virtual ~UNavigationSystemV1();
UPROPERTY()
ANavigationData* MainNavData;
/** special navigation data for managing direct paths, not part of NavDataSet! */
UPROPERTY(Transient)
ANavigationData* AbstractNavData;
protected:
UPROPERTY(config, EditAnywhere, BlueprintReadOnly, Category = Navigation)
TSoftClassPtr<UCrowdManagerBase> CrowdManagerClass;
/** Should navigation system spawn default Navigation Data when there's none and there are navigation bounds present? */
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bAutoCreateNavigationData:1;
UPROPERTY(config, EditAnywhere, Category = NavigationSystem)
uint32 bSpawnNavDataInNavBoundsLevel:1;
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bAllowClientSideNavigation:1;
UPROPERTY(config, EditAnywhere, Category = NavigationSystem)
uint32 bShouldDiscardSubLevelNavData:1;
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bTickWhilePaused:1;
/** gets set to true if gathering navigation data (like in navoctree) is required due to the need of navigation generation
* Is always true in Editor Mode. In other modes it depends on bRebuildAtRuntime of every required NavigationData class' CDO
*/
UPROPERTY()
uint32 bSupportRebuilding : 1;
public:
/** if set to true will result navigation system not rebuild navigation until
* a call to ReleaseInitialBuildingLock() is called. Does not influence
* editor-time generation (i.e. does influence PIE and Game).
* Defaults to false.*/
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bInitialBuildingLocked:1;
/** If set to true (default) navigation will be generated only within special navigation
* bounds volumes (like ANavMeshBoundsVolume). Set to false means navigation should be generated
* everywhere.
*/
// @todo removing it from edition since it's currently broken and I'm not sure we want that at all
// since I'm not sure we can make it efficient in a generic case
//UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bWholeWorldNavigable:1;
/** false by default, if set to true will result in not caring about nav agent height
* when trying to match navigation data to passed in nav agent */
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
uint32 bSkipAgentHeightCheckWhenPickingNavData:1;
protected:
UPROPERTY(EditDefaultsOnly, Category = "NavigationSystem", config)
ENavDataGatheringModeConfig DataGatheringMode;
/** If set to true navigation will be generated only around registered "navigation enforcers"
* This has a range of consequences (including how navigation octree operates) so it needs to
* be a conscious decision.
* Once enabled results in whole world being navigable.
* @see RegisterNavigationInvoker
*/
UPROPERTY(EditDefaultsOnly, Category = "Navigation Enforcing", config)
uint32 bGenerateNavigationOnlyAroundNavigationInvokers : 1;
/** Minimal time, in seconds, between active tiles set update */
UPROPERTY(EditAnywhere, Category = "Navigation Enforcing", meta = (ClampMin = "0.1", UIMin = "0.1", EditCondition = "bGenerateNavigationOnlyAroundNavigationInvokers"), config)
float ActiveTilesUpdateInterval;
UPROPERTY(config, EditAnywhere, Category = Agents)
TArray<FNavDataConfig> SupportedAgents;
public:
/** update frequency for dirty areas on navmesh */
UPROPERTY(config, EditAnywhere, Category=NavigationSystem)
float DirtyAreasUpdateFreq;
UPROPERTY()
TArray<ANavigationData*> NavDataSet;
UPROPERTY(transient)
TArray<ANavigationData*> NavDataRegistrationQueue;
TSet<FNavigationDirtyElement> PendingOctreeUpdates;
// List of pending navigation bounds update requests (add, remove, update size)
TArray<FNavigationBoundsUpdateRequest> PendingNavBoundsUpdates;
UPROPERTY(/*BlueprintAssignable, */Transient)
FOnNavDataGenericEvent OnNavDataRegisteredEvent;
UPROPERTY(BlueprintAssignable, Transient, meta = (displayname = OnNavigationGenerationFinished))
FOnNavDataGenericEvent OnNavigationGenerationFinishedDelegate;
FOnNavigationInitDone OnNavigationInitDone;
private:
TWeakObjectPtr<UCrowdManagerBase> CrowdManager;
/** set to true when navigation processing was blocked due to missing nav bounds */
uint32 bNavDataRemovedDueToMissingNavBounds : 1;
protected:
/** All areas where we build/have navigation */
TSet<FNavigationBounds> RegisteredNavBounds;
private:
TMap<AActor*, FNavigationInvoker> Invokers;
/** Contains pre-digested and cached invokers' info. Generated by UpdateInvokers */
TArray<FNavigationInvokerRaw> InvokerLocations;
float NextInvokersUpdateTime;
void UpdateInvokers();
public:
//----------------------------------------------------------------------//
// Blueprint functions
//----------------------------------------------------------------------//
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject"))
static UNavigationSystemV1* GetNavigationSystem(UObject* WorldContextObject);
/** Project a point onto the NavigationData */
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "ProjectPointToNavigation", ScriptName = "ProjectPointToNavigation"))
static bool K2_ProjectPointToNavigation(UObject* WorldContextObject, const FVector& Point, FVector& ProjectedLocation, ANavigationData* NavData, TSubclassOf<UNavigationQueryFilter> FilterClass, const FVector QueryExtent = FVector::ZeroVector);
/** Generates a random location reachable from given Origin location.
* @return Return Value represents if the call was successful */
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "GetRandomReachablePointInRadius", ScriptName = "GetRandomReachablePointInRadius"))
static bool K2_GetRandomReachablePointInRadius(UObject* WorldContextObject, const FVector& Origin, FVector& RandomLocation, float Radius, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
/** Generates a random location in navigable space within given radius of Origin.
* @return Return Value represents if the call was successful */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "GetRandomLocationInNavigableRadius", ScriptName = "GetRandomLocationInNavigableRadius"))
static bool K2_GetRandomLocationInNavigableRadius(UObject* WorldContextObject, const FVector& Origin, FVector& RandomLocation, float Radius, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
/** Potentially expensive. Use with caution. Consider using UPathFollowingComponent::GetRemainingPathCost instead */
UFUNCTION(BlueprintPure, Category="AI|Navigation", meta=(WorldContext="WorldContextObject" ) )
static ENavigationQueryResult::Type GetPathCost(UObject* WorldContextObject, const FVector& PathStart, const FVector& PathEnd, float& PathCost, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
/** Potentially expensive. Use with caution */
UFUNCTION(BlueprintPure, Category="AI|Navigation", meta=(WorldContext="WorldContextObject" ) )
static ENavigationQueryResult::Type GetPathLength(UObject* WorldContextObject, const FVector& PathStart, const FVector& PathEnd, float& PathLength, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
UFUNCTION(BlueprintPure, Category="AI|Navigation", meta=(WorldContext="WorldContextObject" ) )
static bool IsNavigationBeingBuilt(UObject* WorldContextObject);
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject"))
static bool IsNavigationBeingBuiltOrLocked(UObject* WorldContextObject);
/** Finds path instantly, in a FindPath Synchronously.
* @param PathfindingContext could be one of following: NavigationData (like Navmesh actor), Pawn or Controller. This parameter determines parameters of specific pathfinding query */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (WorldContext="WorldContextObject"))
static UNavigationPath* FindPathToLocationSynchronously(UObject* WorldContextObject, const FVector& PathStart, const FVector& PathEnd, AActor* PathfindingContext = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
/** Finds path instantly, in a FindPath Synchronously. Main advantage over FindPathToLocationSynchronously is that
* the resulting path will automatically get updated if goal actor moves more than TetherDistance away from last path node
* @param PathfindingContext could be one of following: NavigationData (like Navmesh actor), Pawn or Controller. This parameter determines parameters of specific pathfinding query */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (WorldContext="WorldContextObject"))
static UNavigationPath* FindPathToActorSynchronously(UObject* WorldContextObject, const FVector& PathStart, AActor* GoalActor, float TetherDistance = 50.f, AActor* PathfindingContext = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
/** Performs navigation raycast on NavigationData appropriate for given Querier.
* @param Querier if not passed default navigation data will be used
* @param HitLocation if line was obstructed this will be set to hit location. Otherwise it contains SegmentEnd
* @return true if line from RayStart to RayEnd was obstructed. Also, true when no navigation data present */
UFUNCTION(BlueprintCallable, Category="AI|Navigation", meta=(WorldContext="WorldContextObject" ))
static bool NavigationRaycast(UObject* WorldContextObject, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL, AController* Querier = NULL);
/** will limit the number of simultaneously running navmesh tile generation jobs to specified number.
* @param MaxNumberOfJobs gets trimmed to be at least 1. You cannot use this function to pause navmesh generation */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
void SetMaxSimultaneousTileGenerationJobsCount(int32 MaxNumberOfJobs);
/** Brings limit of simultaneous navmesh tile generation jobs back to Project Setting's default value */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
void ResetMaxSimultaneousTileGenerationJobsCount();
/** Registers given actor as a "navigation enforcer" which means navigation system will
* make sure navigation is being generated in specified radius around it.
* @note: you need NavigationSystem's GenerateNavigationOnlyAroundNavigationInvokers to be set to true
* to take advantage of this feature
*/
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
void RegisterNavigationInvoker(AActor* Invoker, float TileGenerationRadius = 3000, float TileRemovalRadius = 5000);
/** Removes given actor from the list of active navigation enforcers.
* @see RegisterNavigationInvoker for more details */
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
void UnregisterNavigationInvoker(AActor* Invoker);
UFUNCTION(BlueprintCallable, Category = "AI|Navigation|Generation")
void SetGeometryGatheringMode(ENavDataGatheringModeConfig NewMode);
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta=(DisplayName="ReplaceAreaInOctreeData"))
bool K2_ReplaceAreaInOctreeData(const UObject* Object, TSubclassOf<UNavArea> OldArea, TSubclassOf<UNavArea> NewArea);
FORCEINLINE bool IsActiveTilesGenerationEnabled() const{ return bGenerateNavigationOnlyAroundNavigationInvokers; }
/** delegate type for events that dirty the navigation data ( Params: const FBox& DirtyBounds ) */
DECLARE_MULTICAST_DELEGATE_OneParam(FOnNavigationDirty, const FBox&);
/** called after navigation influencing event takes place*/
static FOnNavigationDirty NavigationDirtyEvent;
enum ERegistrationResult
{
RegistrationError,
RegistrationFailed_DataPendingKill, // means navigation data being registered is marked as pending kill
RegistrationFailed_AgentAlreadySupported, // this means that navigation agent supported by given nav data is already handled by some other, previously registered instance
RegistrationFailed_AgentNotValid, // given instance contains navmesh that doesn't support any of expected agent types, or instance doesn't specify any agent
RegistrationFailed_NotSuitable, // given instance had been considered unsuitable by current navigation system instance itself
RegistrationSuccessful,
};
enum EOctreeUpdateMode
{
OctreeUpdate_Default = 0, // regular update, mark dirty areas depending on exported content
OctreeUpdate_Geometry = 1, // full update, mark dirty areas for geometry rebuild
OctreeUpdate_Modifiers = 2, // quick update, mark dirty areas for modifier rebuild
OctreeUpdate_Refresh = 4, // update is used for refresh, don't invalidate pending queue
OctreeUpdate_ParentChain = 8, // update child nodes, don't remove anything
};
//~ Begin UObject Interface
virtual void PostInitProperties() override;
static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector);
#if WITH_EDITOR
virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
//~ End UObject Interface
virtual void Tick(float DeltaSeconds) override;
UWorld* GetWorld() const override { return GetOuterUWorld(); }
UCrowdManagerBase* GetCrowdManager() const { return CrowdManager.Get(); }
protected:
/** spawn new crowd manager */
virtual void CreateCrowdManager();
/** Used to properly set navigation class for indicated agent and propagate information to other places
* (like project settings) that may need this information
*/
void SetSupportedAgentsNavigationClass(int32 AgentIndex, TSubclassOf<ANavigationData> NavigationDataClass);
public:
//----------------------------------------------------------------------//
//~ Begin Public querying Interface
//----------------------------------------------------------------------//
/**
* Synchronously looks for a path from @fLocation to @EndLocation for agent with properties @AgentProperties. NavData actor appropriate for specified
* FNavAgentProperties will be found automatically
* @param ResultPath results are put here
* @param NavData optional navigation data that will be used instead of the one that would be deducted from AgentProperties
* @param Mode switch between normal and hierarchical path finding algorithms
*/
FPathFindingResult FindPathSync(const FNavAgentProperties& AgentProperties, FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
/**
* Does a simple path finding from @StartLocation to @EndLocation on specified NavData. If none passed MainNavData will be used
* Result gets placed in ResultPath
* @param NavData optional navigation data that will be used instead main navigation data
* @param Mode switch between normal and hierarchical path finding algorithms
*/
FPathFindingResult FindPathSync(FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
/**
* Asynchronously looks for a path from @StartLocation to @EndLocation for agent with properties @AgentProperties. NavData actor appropriate for specified
* FNavAgentProperties will be found automatically
* @param ResultDelegate delegate that will be called once query has been processed and finished. Will be called even if query fails - in such case see comments for delegate's params
* @param NavData optional navigation data that will be used instead of the one that would be deducted from AgentProperties
* @param PathToFill if points to an actual navigation path instance than this instance will be filled with resulting path. Otherwise a new instance will be created and
* used in call to ResultDelegate
* @param Mode switch between normal and hierarchical path finding algorithms
* @return request ID
*/
uint32 FindPathAsync(const FNavAgentProperties& AgentProperties, FPathFindingQuery Query, const FNavPathQueryDelegate& ResultDelegate, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
/** Removes query indicated by given ID from queue of path finding requests to process. */
void AbortAsyncFindPathRequest(uint32 AsynPathQueryID);
/**
* Synchronously check if path between two points exists
* Does not return path object, but will run faster (especially in hierarchical mode)
* @param Mode switch between normal and hierarchical path finding algorithms. @note Hierarchical mode ignores QueryFilter
* @return true if path exists
*/
bool TestPathSync(FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular, int32* NumVisitedNodes = NULL) const;
/** Finds random point in navigable space
* @param ResultLocation Found point is put here
* @param NavData If NavData == NULL then MainNavData is used.
* @return true if any location found, false otherwise */
bool GetRandomPoint(FNavLocation& ResultLocation, ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL);
/** Finds random, reachable point in navigable space restricted to Radius around Origin
* @param ResultLocation Found point is put here
* @param NavData If NavData == NULL then MainNavData is used.
* @return true if any location found, false otherwise */
bool GetRandomReachablePointInRadius(const FVector& Origin, float Radius, FNavLocation& ResultLocation, ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
/** Finds random, point in navigable space restricted to Radius around Origin. Resulting location is not tested for reachability from the Origin
* @param ResultLocation Found point is put here
* @param NavData If NavData == NULL then MainNavData is used.
* @return true if any location found, false otherwise */
bool GetRandomPointInNavigableRadius(const FVector& Origin, float Radius, FNavLocation& ResultLocation, ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
/** Calculates a path from PathStart to PathEnd and retrieves its cost.
* @NOTE potentially expensive, so use it with caution */
ENavigationQueryResult::Type GetPathCost(const FVector& PathStart, const FVector& PathEnd, float& PathCost, const ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
/** Calculates a path from PathStart to PathEnd and retrieves its overestimated length.
* @NOTE potentially expensive, so use it with caution */
ENavigationQueryResult::Type GetPathLength(const FVector& PathStart, const FVector& PathEnd, float& PathLength, const ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
/** Calculates a path from PathStart to PathEnd and retrieves its overestimated length and cost.
* @NOTE potentially expensive, so use it with caution */
ENavigationQueryResult::Type GetPathLengthAndCost(const FVector& PathStart, const FVector& PathEnd, float& PathLength, float& PathCost, const ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
// @todo document
bool ProjectPointToNavigation(const FVector& Point, FNavLocation& OutLocation, const FVector& Extent = INVALID_NAVEXTENT, const FNavAgentProperties* AgentProperties = NULL, FSharedConstNavQueryFilter QueryFilter = NULL)
{
return ProjectPointToNavigation(Point, OutLocation, Extent, AgentProperties != NULL ? GetNavDataForProps(*AgentProperties) : GetDefaultNavDataInstance(FNavigationSystem::DontCreate), QueryFilter);
}
// @todo document
bool ProjectPointToNavigation(const FVector& Point, FNavLocation& OutLocation, const FVector& Extent = INVALID_NAVEXTENT, const ANavigationData* NavData = NULL, FSharedConstNavQueryFilter QueryFilter = NULL) const;
/**
* Looks for NavData generated for specified movement properties and returns it. NULL if not found;
*/
ANavigationData* GetNavDataForProps(const FNavAgentProperties& AgentProperties);
/**
* Looks for NavData generated for specified movement properties and returns it. NULL if not found; Const version.
*/
const ANavigationData* GetNavDataForProps(const FNavAgentProperties& AgentProperties) const;
/** Returns the world default navigation data instance. Creates one if it doesn't exist. */
ANavigationData* GetDefaultNavDataInstance(FNavigationSystem::ECreateIfMissing CreateNewIfNoneFound);
/** Returns the world default navigation data instance. */
virtual INavigationDataInterface* GetMainNavData() const override { return Cast<INavigationDataInterface>(GetDefaultNavDataInstance()); }
ANavigationData& GetMainNavDataChecked() const { check(MainNavData); return *MainNavData; }
ANavigationData* GetDefaultNavDataInstance() const { return MainNavData; }
ANavigationData* GetAbstractNavData() const { return AbstractNavData; }
/** constructs a navigation data instance of specified NavDataClass, in passed World
* for supplied NavConfig */
virtual ANavigationData* CreateNavigationDataInstance(const FNavDataConfig& NavConfig);
FSharedNavQueryFilter CreateDefaultQueryFilterCopy() const;
/** Super-hacky safety feature for threaded navmesh building. Will be gone once figure out why keeping TSharedPointer to Navigation Generator doesn't
* guarantee its existence */
bool ShouldGeneratorRun(const FNavDataGenerator* Generator) const;
virtual bool IsNavigationBuilt(const AWorldSettings* Settings) const override;
virtual bool IsThereAnywhereToBuildNavigation() const;
bool ShouldGenerateNavigationEverywhere() const { return bWholeWorldNavigable; }
bool ShouldAllowClientSideNavigation() const { return bAllowClientSideNavigation; }
virtual bool ShouldLoadNavigationOnClient(ANavigationData* NavData = nullptr) const { return bAllowClientSideNavigation; }
virtual bool ShouldDiscardSubLevelNavData(ANavigationData* NavData = nullptr) const { return bShouldDiscardSubLevelNavData; }
FBox GetWorldBounds() const;
FBox GetLevelBounds(ULevel* InLevel) const;
bool IsNavigationRelevant(const AActor* TestActor) const;
const TSet<FNavigationBounds>& GetNavigationBounds() const;
static const FNavDataConfig& GetDefaultSupportedAgent();
FORCEINLINE const FNavDataConfig& GetDefaultSupportedAgentConfig() const { check(SupportedAgents.Num() > 0); return SupportedAgents[0]; }
FORCEINLINE const TArray<FNavDataConfig>& GetSupportedAgents() const { return SupportedAgents; }
void OverrideSupportedAgents(const TArray<FNavDataConfig>& NewSupportedAgents);
virtual void ApplyWorldOffset(const FVector& InOffset, bool bWorldShift) override;
/** checks if navigation/navmesh is dirty and needs to be rebuilt */
bool IsNavigationDirty() const;
/** checks if dirty navigation data can rebuild itself */
bool CanRebuildDirtyNavigation() const;
FORCEINLINE bool SupportsNavigationGeneration() const { return bSupportRebuilding; }
static bool DoesPathIntersectBox(const FNavigationPath* Path, const FBox& Box, uint32 StartingIndex = 0, FVector* AgentExtent = NULL);
static bool DoesPathIntersectBox(const FNavigationPath* Path, const FBox& Box, const FVector& AgentLocation, uint32 StartingIndex = 0, FVector* AgentExtent = NULL);
//----------------------------------------------------------------------//
// Active tiles
//----------------------------------------------------------------------//
virtual void RegisterInvoker(AActor& Invoker, float TileGenerationRadius, float TileRemovalRadius);
virtual void UnregisterInvoker(AActor& Invoker);
static void RegisterNavigationInvoker(AActor& Invoker, float TileGenerationRadius, float TileRemovalRadius);
static void UnregisterNavigationInvoker(AActor& Invoker);
const TArray<FNavigationInvokerRaw>& GetInvokerLocations() const { return InvokerLocations; }
//----------------------------------------------------------------------//
// Bookkeeping
//----------------------------------------------------------------------//
// @todo document
virtual void UnregisterNavData(ANavigationData* NavData);
/** adds NavData to registration candidates queue - NavDataRegistrationQueue
* @return true if registration request was successful, false if given NavData
* was deemed unsuitable for registration consideration */
virtual void RequestRegistration(ANavigationData* NavData, bool bTriggerRegistrationProcessing = true);
protected:
/** Processes all NavigationData instances in UWorld owning navigation system instance, and registers
* all previously unregistered */
void RegisterNavigationDataInstances();
/** called in places where we need to spawn the NavOctree, but is checking additional conditions if we really want to do that
* depending on navigation data setup among others
* @return true if NavOctree instance has been created, or if one is already present */
bool ConditionalPopulateNavOctree();
/** Processes registration of candidates queues via RequestRegistration and stored in NavDataRegistrationQueue */
virtual void ProcessRegistrationCandidates();
/** registers CustomLinks awaiting registration in PendingCustomLinkRegistration */
void ProcessCustomLinkPendingRegistration();
/** used to apply updates of nav volumes in navigation system's tick */
void PerformNavigationBoundsUpdate(const TArray<FNavigationBoundsUpdateRequest>& UpdateRequests);
/** adds data to RegisteredNavBounds */
void AddNavigationBounds(const FNavigationBounds& NewBounds);
/** Searches for all valid navigation bounds in the world and stores them */
virtual void GatherNavigationBounds();
/** @return pointer to ANavigationData instance of given ID, or NULL if it was not found. Note it looks only through registered navigation data */
ANavigationData* GetNavDataWithID(const uint16 NavDataID) const;
public:
virtual void ReleaseInitialBuildingLock();
//----------------------------------------------------------------------//
// navigation octree related functions
//----------------------------------------------------------------------//
static void OnComponentRegistered(UActorComponent* Comp);
static void OnComponentUnregistered(UActorComponent* Comp);
static void OnActorRegistered(AActor* Actor);
static void OnActorUnregistered(AActor* Actor);
/** update navoctree entry for specified actor/component */
static void UpdateActorInNavOctree(AActor& Actor);
static void UpdateComponentInNavOctree(UActorComponent& Comp);
/** update all navoctree entries for actor and its components */
static void UpdateActorAndComponentsInNavOctree(AActor& Actor, bool bUpdateAttachedActors = true);
/** update all navoctree entries for actor and its non scene components after root movement */
static void UpdateNavOctreeAfterMove(USceneComponent* Comp);
protected:
/** updates navoctree information on actors attached to RootActor */
static void UpdateAttachedActorsInNavOctree(AActor& RootActor);
public:
/** removes all navoctree entries for actor and its components */
static void ClearNavOctreeAll(AActor* Actor);
/** updates bounds of all components implementing INavRelevantInterface */
static void UpdateNavOctreeBounds(AActor* Actor);
void AddDirtyArea(const FBox& NewArea, int32 Flags);
void AddDirtyAreas(const TArray<FBox>& NewAreas, int32 Flags);
bool HasDirtyAreasQueued() const;
const FNavigationOctree* GetNavOctree() const { return NavOctree.Get(); }
FNavigationOctree* GetMutableNavOctree() { return NavOctree.Get(); }
FORCEINLINE static uint32 HashObject(const UObject& Object)
{
return Object.GetUniqueID();
}
FORCEINLINE void SetObjectsNavOctreeId(const UObject& Object, FOctreeElementId Id) { ObjectToOctreeId.Add(HashObject(Object), Id); }
FORCEINLINE const FOctreeElementId* GetObjectsNavOctreeId(const UObject& Object) const { return ObjectToOctreeId.Find(HashObject(Object)); }
FORCEINLINE bool HasPendingObjectNavOctreeId(UObject* Object) const { return PendingOctreeUpdates.Contains(FNavigationDirtyElement(Object)); }
FORCEINLINE void RemoveObjectsNavOctreeId(const UObject& Object) { ObjectToOctreeId.Remove(HashObject(Object)); }
void RemoveNavOctreeElementId(const FOctreeElementId& ElementId, int32 UpdateFlags);
const FNavigationRelevantData* GetDataForObject(const UObject& Object) const;
FNavigationRelevantData* GetMutableDataForObject(const UObject& Object);
/** find all elements in navigation octree within given box (intersection) */
void FindElementsInNavOctree(const FBox& QueryBox, const FNavigationOctreeFilter& Filter, TArray<FNavigationOctreeElement>& Elements);
/** update single element in navoctree */
void UpdateNavOctreeElement(UObject* ElementOwner, INavRelevantInterface* ElementInterface, int32 UpdateFlags);
/** force updating parent node and all its children */
void UpdateNavOctreeParentChain(UObject* ElementOwner, bool bSkipElementOwnerUpdate = false);
/** update component bounds in navigation octree and mark only specified area as dirty, doesn't re-export component geometry */
bool UpdateNavOctreeElementBounds(UActorComponent* Comp, const FBox& NewBounds, const FBox& DirtyArea);
/** fetched Object's data from the octree and replaces occurences of OldArea with NewArea */
bool ReplaceAreaInOctreeData(const UObject& Object, TSubclassOf<UNavArea> OldArea, TSubclassOf<UNavArea> NewArea, bool bReplaceChildClasses = false);
//----------------------------------------------------------------------//
// Custom navigation links
//----------------------------------------------------------------------//
void RegisterCustomLink(INavLinkCustomInterface& CustomLink);
void UnregisterCustomLink(INavLinkCustomInterface& CustomLink);
static void RequestCustomLinkRegistering(INavLinkCustomInterface& CustomLink, UObject* OwnerOb);
static void RequestCustomLinkUnregistering(INavLinkCustomInterface& CustomLink, UObject* ObjectOb);
/** find custom link by unique ID */
INavLinkCustomInterface* GetCustomLink(uint32 UniqueLinkId) const;
/** updates custom link for all active navigation data instances */
void UpdateCustomLink(const INavLinkCustomInterface* CustomLink);
//----------------------------------------------------------------------//
// Areas
//----------------------------------------------------------------------//
static void RequestAreaRegistering(UClass* NavAreaClass);
static void RequestAreaUnregistering(UClass* NavAreaClass);
/** find index in SupportedAgents array for given navigation data */
int32 GetSupportedAgentIndex(const ANavigationData* NavData) const;
/** find index in SupportedAgents array for agent type */
int32 GetSupportedAgentIndex(const FNavAgentProperties& NavAgent) const;
//----------------------------------------------------------------------//
// Filters
//----------------------------------------------------------------------//
/** prepare descriptions of navigation flags in UNavigationQueryFilter class: using enum */
void DescribeFilterFlags(UEnum* FlagsEnum) const;
/** prepare descriptions of navigation flags in UNavigationQueryFilter class: using array */
void DescribeFilterFlags(const TArray<FString>& FlagsDesc) const;
/** removes cached filters from currently registered navigation data */
void ResetCachedFilter(TSubclassOf<UNavigationQueryFilter> FilterClass);
//----------------------------------------------------------------------//
// building
//----------------------------------------------------------------------//
/** Triggers navigation building on all eligible navigation data. */
virtual void Build();
/** Cancels all currently running navigation builds */
virtual void CancelBuild();
// @todo document
void OnPIEStart();
// @todo document
void OnPIEEnd();
// @todo document
FORCEINLINE bool IsNavigationBuildingLocked() const { return NavBuildingLockFlags != 0; }
/** check if building is permanently locked to avoid showing navmesh building notify (due to queued dirty areas) */
FORCEINLINE bool IsNavigationBuildingPermanentlyLocked() const
{
return (NavBuildingLockFlags & ~ENavigationBuildLock::InitialLock) != 0;
}
/** check if navigation octree updates are currently ignored */
FORCEINLINE bool IsNavigationOctreeLocked() const { return bNavOctreeLock; }
// @todo document
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
void OnNavigationBoundsUpdated(ANavMeshBoundsVolume* NavVolume);
virtual void OnNavigationBoundsAdded(ANavMeshBoundsVolume* NavVolume);
void OnNavigationBoundsRemoved(ANavMeshBoundsVolume* NavVolume);
/** Used to display "navigation building in progress" notify */
bool IsNavigationBuildInProgress(bool bCheckDirtyToo = true);
virtual void OnNavigationGenerationFinished(ANavigationData& NavData);
/** Used to display "navigation building in progress" counter */
int32 GetNumRemainingBuildTasks() const;
/** Number of currently running tasks */
int32 GetNumRunningBuildTasks() const;
protected:
/** Sets up SuportedAgents and NavigationDataCreators. Override it to add additional setup, but make sure to call Super implementation */
virtual void DoInitialSetup();
/** spawn new crowd manager */
virtual void UpdateAbstractNavData();
/** Called during ConditionalPopulateNavOctree and gives subclassess a chance
* to influence what gets added */
virtual void AddLevelToOctree(ULevel& Level);
public:
/** Called upon UWorld destruction to release what needs to be released */
virtual void CleanUp(const FNavigationSystem::ECleanupMode Mode = FNavigationSystem::ECleanupMode::CleanupUnsafe) override;
/**
* Called when owner-UWorld initializes actors
*/
virtual void OnInitializeActors() override;
/** */
virtual void OnWorldInitDone(FNavigationSystemRunMode Mode);
FORCEINLINE bool IsInitialized() const { return bWorldInitDone; }
/** adds BSP collisions of currently streamed in levels to octree */
void InitializeLevelCollisions();
FORCEINLINE void AddNavigationBuildLock(uint8 Flags) { NavBuildingLockFlags |= Flags; }
void RemoveNavigationBuildLock(uint8 Flags, bool bSkipRebuildInEditor = false);
void SetNavigationOctreeLock(bool bLock) { bNavOctreeLock = bLock; }
/** checks if auto-rebuilding navigation data is enabled. Defaults to bNavigationAutoUpdateEnabled
* value, but can be overridden per nav sys instance */
virtual bool GetIsAutoUpdateEnabled() const { return bNavigationAutoUpdateEnabled; }
#if WITH_EDITOR
/** allow editor to toggle whether seamless navigation building is enabled */
static void SetNavigationAutoUpdateEnabled(bool bNewEnable, UNavigationSystemBase* InNavigationSystem);
FORCEINLINE bool IsNavigationRegisterLocked() const { return NavUpdateLockFlags != 0; }
FORCEINLINE bool IsNavigationUnregisterLocked() const { return NavUpdateLockFlags && !(NavUpdateLockFlags & ENavigationLockReason::AllowUnregister); }
FORCEINLINE bool IsNavigationUpdateLocked() const { return IsNavigationRegisterLocked(); }
FORCEINLINE void AddNavigationUpdateLock(uint8 Flags) { NavUpdateLockFlags |= Flags; }
FORCEINLINE void RemoveNavigationUpdateLock(uint8 Flags) { NavUpdateLockFlags &= ~Flags; }
void UpdateLevelCollision(ULevel* InLevel);
virtual void OnEditorModeChanged(FEdMode* Mode, bool IsEntering);
#endif // WITH_EDITOR
FORCEINLINE bool IsSetUpForLazyGeometryExporting() const { return bGenerateNavigationOnlyAroundNavigationInvokers; }
static UNavigationSystemV1* CreateNavigationSystem(UWorld* WorldOwner);
static UNavigationSystemV1* GetCurrent(UWorld* World);
static UNavigationSystemV1* GetCurrent(UObject* WorldContextObject);
virtual void InitializeForWorld(UWorld& World, FNavigationSystemRunMode Mode) override;
// Fetch the array of all nav-agent properties.
void GetNavAgentPropertiesArray(TArray<FNavAgentProperties>& OutNavAgentProperties) const;
static FORCEINLINE bool ShouldUpdateNavOctreeOnComponentChange()
{
return (bUpdateNavOctreeOnComponentChange && !bStaticRuntimeNavigation)
#if WITH_EDITOR
|| (GIsEditor && !GIsPlayInEditorWorld)
#endif
;
}
static FORCEINLINE bool IsNavigationSystemStatic()
{
return bStaticRuntimeNavigation
#if WITH_EDITOR
&& !(GIsEditor && !GIsPlayInEditorWorld)
#endif
;
}
/** Use this function to signal the NavigationSystem it doesn't need to store
* any navigation-generation-related data at game runtime, because
* nothing is going to use it anyway. This will short-circuit all code related
* to navmesh rebuilding, so use it only if you have fully static navigation in
* your game.
* Note: this is not a runtime switch. Call it before any actual game starts. */
static void ConfigureAsStatic();
static void SetUpdateNavOctreeOnComponentChange(bool bNewUpdateOnComponentChange);
/**
* Exec command handlers
*/
bool HandleCycleNavDrawnCommand( const TCHAR* Cmd, FOutputDevice& Ar );
bool HandleCountNavMemCommand();
//----------------------------------------------------------------------//
// debug
//----------------------------------------------------------------------//
void CycleNavigationDataDrawn();
protected:
UPROPERTY()
FNavigationSystemRunMode OperationMode;
TSharedPtr<FNavigationOctree, ESPMode::ThreadSafe> NavOctree;
TArray<FAsyncPathFindingQuery> AsyncPathFindingQueries;
FCriticalSection NavDataRegistration;
TMap<FNavAgentProperties, TWeakObjectPtr<ANavigationData> > AgentToNavDataMap;
TMap<uint32, FOctreeElementId> ObjectToOctreeId;
/** Map of all objects that are tied to indexed navigation parent */
TMultiMap<UObject*, FWeakObjectPtr> OctreeChildNodesMap;
/** Map of all custom navigation links, that are relevant for path following */
TMap<uint32, FNavigationSystem::FCustomLinkOwnerInfo> CustomLinksMap;
/** stores areas marked as dirty throughout the frame, processes them
* once a frame in Tick function */
TArray<FNavigationDirtyArea> DirtyAreas;
// async queries
FCriticalSection NavDataRegistrationSection;
static FCriticalSection CustomLinkRegistrationSection;
#if WITH_EDITOR
uint8 NavUpdateLockFlags;
#endif
uint8 NavBuildingLockFlags;
/** set of locking flags applied on startup of navigation system */
uint8 InitialNavBuildingLockFlags;
/** if set, navoctree updates are ignored, use with caution! */
uint8 bNavOctreeLock : 1;
uint8 bInitialSetupHasBeenPerformed : 1;
uint8 bInitialLevelsAdded : 1;
uint8 bWorldInitDone : 1;
uint8 bAsyncBuildPaused : 1; // mz@todo remove, replaced by bIsPIEActive and IsGameWorld
uint8 bCanAccumulateDirtyAreas : 1;
#if !UE_BUILD_SHIPPING
uint8 bDirtyAreasReportedWhileAccumulationLocked : 1;
#endif // !UE_BUILD_SHIPPING
/** cached navigable world bounding box*/
mutable FBox NavigableWorldBounds;
/** indicates which of multiple navigation data instances to draw*/
int32 CurrentlyDrawnNavDataIndex;
/** temporary cumulative time to calculate when we need to update dirty areas */
float DirtyAreasUpdateTime;
#if !UE_BUILD_SHIPPING
/** self-registering exec command to handle nav sys console commands */
static FNavigationSystemExec ExecHandler;
#endif // !UE_BUILD_SHIPPING
/** whether seamless navigation building is enabled */
static bool bNavigationAutoUpdateEnabled;
static bool bUpdateNavOctreeOnComponentChange;
static bool bStaticRuntimeNavigation;
static bool bIsPIEActive;
static TMap<INavLinkCustomInterface*, FWeakObjectPtr> PendingCustomLinkRegistration;
TSet<const UClass*> NavAreaClasses;
/** delegate handler for PostLoadMap event */
void OnPostLoadMap(UWorld* LoadedWorld);
#if WITH_EDITOR
/** delegate handler for ActorMoved events */
void OnActorMoved(AActor* Actor);
#endif
/** delegate handler called when navigation is dirtied*/
void OnNavigationDirtied(const FBox& Bounds);
#if WITH_HOT_RELOAD
FDelegateHandle HotReloadDelegateHandle;
/** called to notify NavigaitonSystem about finished hot reload */
virtual void OnHotReload(bool bWasTriggeredAutomatically);
#endif // WITH_HOT_RELOAD
/** Registers given navigation data with this Navigation System.
* @return RegistrationSuccessful if registration was successful, other results mean it failed
* @see ERegistrationResult
*/
virtual ERegistrationResult RegisterNavData(ANavigationData* NavData);
/** tries to register navigation area */
void RegisterNavAreaClass(UClass* NavAreaClass);
/** tries to unregister navigation area */
void UnregisterNavAreaClass(UClass* NavAreaClass);
void OnNavigationAreaEvent(UClass* AreaClass, ENavAreaEvent::Type Event);
FSetElementId RegisterNavOctreeElement(UObject* ElementOwner, INavRelevantInterface* ElementInterface, int32 UpdateFlags);
void UnregisterNavOctreeElement(UObject* ElementOwner, INavRelevantInterface* ElementInterface, int32 UpdateFlags);
/** read element data from navigation octree */
bool GetNavOctreeElementData(const UObject& NodeOwner, int32& DirtyFlags, FBox& DirtyBounds);
//bool GetNavOctreeElementData(UObject* NodeOwner, int32& DirtyFlags, FBox& DirtyBounds);
/** Adds given element to NavOctree. No check for owner's validity are performed,
* nor its presence in NavOctree - function assumes callee responsibility
* in this regard **/
void AddElementToNavOctree(const FNavigationDirtyElement& DirtyElement);
void SetCrowdManager(UCrowdManagerBase* NewCrowdManager);
/** Add BSP collision data to navigation octree */
void AddLevelCollisionToOctree(ULevel* Level);
/** Remove BSP collision data from navigation octree */
void RemoveLevelCollisionFromOctree(ULevel* Level);
virtual void SpawnMissingNavigationData();
protected:
virtual void RebuildDirtyAreas();
private:
// adds navigation bounds update request to a pending list
void AddNavigationBoundsUpdateRequest(const FNavigationBoundsUpdateRequest& UpdateRequest);
/** Triggers navigation building on all eligible navigation data. */
void RebuildAll(bool bIsLoadTime = false);
/** Handler for FWorldDelegates::LevelAddedToWorld event */
void OnLevelAddedToWorld(ULevel* InLevel, UWorld* InWorld);
/** Handler for FWorldDelegates::LevelRemovedFromWorld event */
void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld);
/** Adds given request to requests queue. Note it's to be called only on game thread only */
void AddAsyncQuery(const FAsyncPathFindingQuery& Query);
/** spawns a non-game-thread task to process requests given in PathFindingQueries.
* In the process PathFindingQueries gets copied. */
void TriggerAsyncQueries(TArray<FAsyncPathFindingQuery>& PathFindingQueries);
/** Processes pathfinding requests given in PathFindingQueries.*/
void PerformAsyncQueries(TArray<FAsyncPathFindingQuery> PathFindingQueries);
/** */
void DestroyNavOctree();
/** Whether Navigation system needs to populate nav octree.
* Depends on runtime generation settings of each navigation data, always true in the editor
*/
bool RequiresNavOctree() const;
/** Return "Strongest" runtime generation type required by registered navigation data objects
* Depends on runtime generation settings of each navigation data, always ERuntimeGenerationType::Dynamic in the editor world
*/
ERuntimeGenerationType GetRuntimeGenerationType() const;
//----------------------------------------------------------------------//
// new stuff
//----------------------------------------------------------------------//
public:
void VerifyNavigationRenderingComponents(const bool bShow);
virtual int GetNavigationBoundsForNavData(const ANavigationData& NavData, TArray<FBox>& OutBounds) const;
static INavigationDataInterface* GetNavDataForActor(const AActor& Actor);
virtual void Configure(const UNavigationSystemConfig& Config);
#if !UE_BUILD_SHIPPING
void GetOnScreenMessages(TMultiMap<FCoreDelegates::EOnScreenMessageSeverity, FText>& OutMessages);
#endif // !UE_BUILD_SHIPPING
//----------------------------------------------------------------------//
// DEPRECATED
//----------------------------------------------------------------------//
public:
UE_DEPRECATED(4.16, "This version of ProjectPointToNavigation is deprecated. Please use the new version")
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "ProjectPointToNavigation_DEPRECATED", ScriptNoExport, DeprecatedFunction, DeprecationMessage = "This version of ProjectPointToNavigation is deprecated. Please use the new version"))
static FVector ProjectPointToNavigation(UObject* WorldContextObject, const FVector& Point, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL, const FVector QueryExtent = FVector::ZeroVector);
UE_DEPRECATED(4.16, "This version of GetRandomReachablePointInRadius is deprecated. Please use the new version")
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "GetRandomReachablePointInRadius_DEPRECATED", ScriptNoExport, DeprecatedFunction, DeprecationMessage = "This version of GetRandomReachablePointInRadius is deprecated. Please use the new version"))
static FVector GetRandomReachablePointInRadius(UObject* WorldContextObject, const FVector& Origin, float Radius, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
UE_DEPRECATED(4.16, "This version of GetRandomPointInNavigableRadius is deprecated. Please use the new version")
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "GetRandomPointInNavigableRadius_DEPRECATED", ScriptNoExport, DeprecatedFunction, DeprecationMessage = "This version of GetRandomPointInNavigableRadius is deprecated. Please use the new version"))
static FVector GetRandomPointInNavigableRadius(UObject* WorldContextObject, const FVector& Origin, float Radius, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
UE_DEPRECATED(4.20, "SimpleMoveToActor is deprecated. Use UAIBlueprintHelperLibrary::SimpleMoveToActor instead")
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (DisplayName = "SimpleMoveToActor_DEPRECATED", ScriptNoExport, DeprecatedFunction, DeprecationMessage = "SimpleMoveToActor is deprecated. Use AIBlueprintHelperLibrary::SimpleMoveToActor instead"))
static void SimpleMoveToActor(AController* Controller, const AActor* Goal);
UE_DEPRECATED(4.20, "SimpleMoveToLocation is deprecated. Use UAIBlueprintHelperLibrary::SimpleMoveToLocation instead")
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (DisplayName = "SimpleMoveToLocation_DEPRECATED", ScriptNoExport, DeprecatedFunction, DeprecationMessage = "SimpleMoveToLocation is deprecated. Use AIBlueprintHelperLibrary::SimpleMoveToLocation instead"))
static void SimpleMoveToLocation(AController* Controller, const FVector& Goal);
UE_DEPRECATED(4.20, "UNavigationSystem::GetDefaultWalkableArea is deprecated. Use FNavigationSystem::GetDefaultWalkableArea instead")
static TSubclassOf<UNavAreaBase> GetDefaultWalkableArea() { return FNavigationSystem::GetDefaultWalkableArea(); }
UE_DEPRECATED(4.20, "UNavigationSystem::GetDefaultObstacleArea is deprecated. Use FNavigationSystem::GetDefaultObstacleArea instead")
static TSubclassOf<UNavAreaBase> GetDefaultObstacleArea() { return FNavigationSystem::GetDefaultObstacleArea(); }
UE_DEPRECATED(4.22, "This version is deprecated. Please use GetRandomLocationInNavigableRadius instead")
UFUNCTION(BlueprintPure, Category = "AI|Navigation", meta = (WorldContext = "WorldContextObject", DisplayName = "GetRandomPointInNavigableRadius", ScriptName = "GetRandomPointInNavigableRadius"))
static bool K2_GetRandomPointInNavigableRadius(UObject* WorldContextObject, const FVector& Origin, FVector& RandomLocation, float Radius, ANavigationData* NavData = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
};
//----------------------------------------------------------------------//
// UNavigationSystemModuleConfig
//----------------------------------------------------------------------//
UCLASS()
class NAVIGATIONSYSTEM_API UNavigationSystemModuleConfig : public UNavigationSystemConfig
{
GENERATED_BODY()
protected:
/** Whether at game runtime we expect any kind of dynamic navigation generation */
UPROPERTY(EditAnywhere, Category = Navigation)
uint32 bStrictlyStatic : 1;
UPROPERTY(EditAnywhere, Category = Navigation)
uint32 bCreateOnClient : 1;
UPROPERTY(EditAnywhere, Category = Navigation)
uint32 bAutoSpawnMissingNavData : 1;
UPROPERTY(EditAnywhere, Category = Navigation)
uint32 bSpawnNavDataInNavBoundsLevel : 1;
public:
UNavigationSystemModuleConfig(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
virtual void PostInitProperties() override;
virtual UNavigationSystemBase* CreateAndConfigureNavigationSystem(UWorld& World) const override;
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif // WITH_EDITOR
protected:
#if WITH_EDITOR
friend UNavigationSystemV1;
#endif // WITH_EDITOR
void UpdateWithNavSysCDO(const UNavigationSystemV1& NavSysCDO);
};