mirror of
https://github.com/ApfelTeeSaft/F4Menu.git
synced 2026-08-26 19:23:28 +00:00
more junk
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
{
|
||||
public class AIModule : ModuleRules
|
||||
{
|
||||
public AIModule(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"Runtime/NavigationSystem/Public",
|
||||
"Runtime/AIModule/Public",
|
||||
}
|
||||
);
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"Runtime/AIModule/Private",
|
||||
"Runtime/Engine/Private",
|
||||
}
|
||||
);
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[] {
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"GameplayTags",
|
||||
"GameplayTasks",
|
||||
"NavigationSystem",
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[] {
|
||||
"RHI",
|
||||
"RenderCore",
|
||||
}
|
||||
);
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[] {
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
|
||||
if (Target.bBuildEditor == true)
|
||||
{
|
||||
PrivateDependencyModuleNames.Add("UnrealEd");
|
||||
|
||||
PrivateDependencyModuleNames.Add("AITestSuite");
|
||||
CircularlyReferencedDependentModules.Add("AITestSuite");
|
||||
}
|
||||
|
||||
if (Target.bCompileRecast)
|
||||
{
|
||||
PrivateDependencyModuleNames.Add("Navmesh");
|
||||
PublicDefinitions.Add("WITH_RECAST=1");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Because we test WITH_RECAST in public Engine header files, we need to make sure that modules
|
||||
// that import us also have this definition set appropriately. Recast is a private dependency
|
||||
// module, so it's definitions won't propagate to modules that import Engine.
|
||||
PublicDefinitions.Add("WITH_RECAST=0");
|
||||
}
|
||||
|
||||
if (Target.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test))
|
||||
{
|
||||
PrivateDependencyModuleNames.Add("GameplayDebugger");
|
||||
PublicDefinitions.Add("WITH_GAMEPLAY_DEBUGGER=1");
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicDefinitions.Add("WITH_GAMEPLAY_DEBUGGER=0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,461 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "NavFilters/NavigationQueryFilter.h"
|
||||
#include "AITypes.h"
|
||||
#include "GameplayTaskOwnerInterface.h"
|
||||
#include "GameplayTask.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "GameFramework/Controller.h"
|
||||
#include "Navigation/PathFollowingComponent.h"
|
||||
#include "Perception/AIPerceptionListenerInterface.h"
|
||||
#include "GenericTeamAgentInterface.h"
|
||||
#include "VisualLogger/VisualLoggerDebugSnapshotInterface.h"
|
||||
#include "AIController.generated.h"
|
||||
|
||||
class FDebugDisplayInfo;
|
||||
class UAIPerceptionComponent;
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
class UBlackboardData;
|
||||
class UBrainComponent;
|
||||
class UCanvas;
|
||||
class UGameplayTaskResource;
|
||||
class UGameplayTasksComponent;
|
||||
class UPawnAction;
|
||||
class UPawnActionsComponent;
|
||||
struct FVisualLogEntry;
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
struct FVisualLogEntry;
|
||||
#endif // ENABLE_VISUAL_LOG
|
||||
struct FPathFindingQuery;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAIMoveCompletedSignature, FAIRequestID, RequestID, EPathFollowingResult::Type, Result);
|
||||
|
||||
// the reason for this being namespace instead of a regular enum is
|
||||
// so that it can be expanded in game-specific code
|
||||
// @todo this is a bit messy, needs to be refactored
|
||||
namespace EAIFocusPriority
|
||||
{
|
||||
typedef uint8 Type;
|
||||
|
||||
const Type Default = 0;
|
||||
const Type Move = 1;
|
||||
const Type Gameplay = 2;
|
||||
|
||||
const Type LastFocusPriority = Gameplay;
|
||||
}
|
||||
|
||||
struct FFocusKnowledge
|
||||
{
|
||||
struct FFocusItem
|
||||
{
|
||||
TWeakObjectPtr<AActor> Actor;
|
||||
FVector Position;
|
||||
|
||||
FFocusItem()
|
||||
{
|
||||
Actor = nullptr;
|
||||
Position = FAISystem::InvalidLocation;
|
||||
}
|
||||
};
|
||||
|
||||
TArray<FFocusItem> Priorities;
|
||||
};
|
||||
|
||||
//~=============================================================================
|
||||
/**
|
||||
* AIController is the base class of controllers for AI-controlled Pawns.
|
||||
*
|
||||
* Controllers are non-physical actors that can be attached to a pawn to control its actions.
|
||||
* AIControllers manage the artificial intelligence for the pawns they control.
|
||||
* In networked games, they only exist on the server.
|
||||
*
|
||||
* @see https://docs.unrealengine.com/latest/INT/Gameplay/Framework/Controller/
|
||||
*/
|
||||
|
||||
UCLASS(ClassGroup = AI, BlueprintType, Blueprintable)
|
||||
class AIMODULE_API AAIController : public AController, public IAIPerceptionListenerInterface, public IGameplayTaskOwnerInterface, public IGenericTeamAgentInterface, public IVisualLoggerDebugSnapshotInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
FGameplayResourceSet ScriptClaimedResources;
|
||||
protected:
|
||||
FFocusKnowledge FocusInformation;
|
||||
|
||||
/** By default AI's logic does not start when controlled Pawn is possessed. Setting this flag to true
|
||||
* will make AI logic start when pawn is possessed */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bStartAILogicOnPossess : 1;
|
||||
|
||||
/** By default AI's logic gets stopped when controlled Pawn is unpossessed. Setting this flag to false
|
||||
* will make AI logic persist past losing control over a pawn */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bStopAILogicOnUnposses : 1;
|
||||
|
||||
public:
|
||||
/** used for alternating LineOfSight traces */
|
||||
UPROPERTY()
|
||||
mutable uint32 bLOSflag : 1;
|
||||
|
||||
/** Skip extra line of sight traces to extremities of target being checked. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bSkipExtraLOSChecks : 1;
|
||||
|
||||
/** Is strafing allowed during movement? */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bAllowStrafe : 1;
|
||||
|
||||
/** Specifies if this AI wants its own PlayerState. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bWantsPlayerState : 1;
|
||||
|
||||
/** Copy Pawn rotation to ControlRotation, if there is no focus point. */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
uint32 bSetControlRotationFromPawnOrientation:1;
|
||||
|
||||
private:
|
||||
|
||||
/** Component used for moving along a path. */
|
||||
UPROPERTY(VisibleDefaultsOnly, Category = AI)
|
||||
UPathFollowingComponent* PathFollowingComponent;
|
||||
|
||||
public:
|
||||
|
||||
/** Component responsible for behaviors. */
|
||||
UPROPERTY(BlueprintReadWrite, Category = AI)
|
||||
UBrainComponent* BrainComponent;
|
||||
|
||||
UPROPERTY(VisibleDefaultsOnly, Category = AI)
|
||||
UAIPerceptionComponent* PerceptionComponent;
|
||||
|
||||
private:
|
||||
UPROPERTY(BlueprintReadOnly, Category = AI, meta = (AllowPrivateAccess = "true"))
|
||||
UPawnActionsComponent* ActionsComp;
|
||||
|
||||
protected:
|
||||
/** blackboard */
|
||||
UPROPERTY(BlueprintReadOnly, Category = AI, meta = (AllowPrivateAccess = "true"))
|
||||
UBlackboardComponent* Blackboard;
|
||||
|
||||
UPROPERTY()
|
||||
UGameplayTasksComponent* CachedGameplayTasksComponent;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AI)
|
||||
TSubclassOf<UNavigationQueryFilter> DefaultNavigationFilterClass;
|
||||
|
||||
public:
|
||||
|
||||
AAIController(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual void SetPawn(APawn* InPawn) override;
|
||||
|
||||
/** Makes AI go toward specified Goal actor (destination will be continuously updated), aborts any active path following
|
||||
* @param AcceptanceRadius - finish move if pawn gets close enough
|
||||
* @param bStopOnOverlap - add pawn's radius to AcceptanceRadius
|
||||
* @param bUsePathfinding - use navigation data to calculate path (otherwise it will go in straight line)
|
||||
* @param bCanStrafe - set focus related flag: bAllowStrafe
|
||||
* @param FilterClass - navigation filter for pathfinding adjustments. If none specified DefaultNavigationFilterClass will be used
|
||||
* @param bAllowPartialPath - use incomplete path when goal can't be reached
|
||||
* @note AcceptanceRadius has default value or -1 due to Header Parser not being able to recognize UPathFollowingComponent::DefaultAcceptanceRadius
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", Meta = (AdvancedDisplay = "bStopOnOverlap,bCanStrafe,bAllowPartialPath"))
|
||||
EPathFollowingRequestResult::Type MoveToActor(AActor* Goal, float AcceptanceRadius = -1, bool bStopOnOverlap = true,
|
||||
bool bUsePathfinding = true, bool bCanStrafe = true,
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass = NULL, bool bAllowPartialPath = true);
|
||||
|
||||
/** Makes AI go toward specified Dest location, aborts any active path following
|
||||
* @param AcceptanceRadius - finish move if pawn gets close enough
|
||||
* @param bStopOnOverlap - add pawn's radius to AcceptanceRadius
|
||||
* @param bUsePathfinding - use navigation data to calculate path (otherwise it will go in straight line)
|
||||
* @param bProjectDestinationToNavigation - project location on navigation data before using it
|
||||
* @param bCanStrafe - set focus related flag: bAllowStrafe
|
||||
* @param FilterClass - navigation filter for pathfinding adjustments. If none specified DefaultNavigationFilterClass will be used
|
||||
* @param bAllowPartialPath - use incomplete path when goal can't be reached
|
||||
* @note AcceptanceRadius has default value or -1 due to Header Parser not being able to recognize UPathFollowingComponent::DefaultAcceptanceRadius
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation", Meta = (AdvancedDisplay = "bStopOnOverlap,bCanStrafe,bAllowPartialPath"))
|
||||
EPathFollowingRequestResult::Type MoveToLocation(const FVector& Dest, float AcceptanceRadius = -1, bool bStopOnOverlap = true,
|
||||
bool bUsePathfinding = true, bool bProjectDestinationToNavigation = false, bool bCanStrafe = true,
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass = NULL, bool bAllowPartialPath = true);
|
||||
|
||||
/** Makes AI go toward specified destination
|
||||
* @param MoveRequest - details about move
|
||||
* @param OutPath - optional output param, filled in with assigned path
|
||||
* @return struct holding MoveId and enum code
|
||||
*/
|
||||
virtual FPathFollowingRequestResult MoveTo(const FAIMoveRequest& MoveRequest, FNavPathSharedPtr* OutPath = nullptr);
|
||||
|
||||
/** Passes move request and path object to path following */
|
||||
virtual FAIRequestID RequestMove(const FAIMoveRequest& MoveRequest, FNavPathSharedPtr Path);
|
||||
|
||||
/** Finds path for given move request
|
||||
* @param MoveRequest - details about move
|
||||
* @param Query - pathfinding query for navigation system
|
||||
* @param OutPath - generated path
|
||||
*/
|
||||
virtual void FindPathForMoveRequest(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query, FNavPathSharedPtr& OutPath) const;
|
||||
|
||||
/** Helper function for creating pathfinding query for this agent from move request data */
|
||||
bool BuildPathfindingQuery(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query) const;
|
||||
|
||||
UE_DEPRECATED_FORGAME(4.13, "This function is now deprecated, please use FindPathForMoveRequest() for adjusting Query or BuildPathfindingQuery() for getting one.")
|
||||
virtual bool PreparePathfinding(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query);
|
||||
|
||||
UE_DEPRECATED_FORGAME(4.13, "This function is now deprecated, please use FindPathForMoveRequest() for adjusting pathfinding or path postprocess.")
|
||||
virtual FAIRequestID RequestPathAndMove(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query);
|
||||
|
||||
/** if AI is currently moving due to request given by RequestToPause, then the move will be paused */
|
||||
bool PauseMove(FAIRequestID RequestToPause);
|
||||
|
||||
/** resumes last AI-performed, paused request provided it's ID was equivalent to RequestToResume */
|
||||
bool ResumeMove(FAIRequestID RequestToResume);
|
||||
|
||||
/** Aborts the move the controller is currently performing */
|
||||
virtual void StopMovement() override;
|
||||
|
||||
/** Called on completing current movement request */
|
||||
virtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result);
|
||||
|
||||
UE_DEPRECATED_FORGAME(4.13, "This function is now deprecated, please use version with EPathFollowingResultDetails parameter.")
|
||||
virtual void OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type Result);
|
||||
|
||||
/** Returns the Move Request ID for the current move */
|
||||
FORCEINLINE FAIRequestID GetCurrentMoveRequestID() const { return GetPathFollowingComponent() ? GetPathFollowingComponent()->GetCurrentRequestId() : FAIRequestID::InvalidRequest; }
|
||||
|
||||
/** Blueprint notification that we've completed the current movement request */
|
||||
UPROPERTY(BlueprintAssignable, meta = (DisplayName = "MoveCompleted"))
|
||||
FAIMoveCompletedSignature ReceiveMoveCompleted;
|
||||
|
||||
TSubclassOf<UNavigationQueryFilter> GetDefaultNavigationFilterClass() const { return DefaultNavigationFilterClass; }
|
||||
|
||||
/** Returns status of path following */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
EPathFollowingStatus::Type GetMoveStatus() const;
|
||||
|
||||
/** Returns true if the current PathFollowingComponent's path is partial (does not reach desired destination). */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
bool HasPartialPath() const;
|
||||
|
||||
/** Returns position of current path segment's end. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
FVector GetImmediateMoveDestination() const;
|
||||
|
||||
/** Updates state of movement block detection. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
void SetMoveBlockDetection(bool bEnable);
|
||||
|
||||
/** Starts executing behavior tree. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI")
|
||||
virtual bool RunBehaviorTree(UBehaviorTree* BTAsset);
|
||||
|
||||
/**
|
||||
* Makes AI use the specified Blackboard asset & creates a Blackboard Component if one does not already exist.
|
||||
* @param BlackboardAsset The Blackboard asset to use.
|
||||
* @param BlackboardComponent The Blackboard component that was used or created to work with the passed-in Blackboard Asset.
|
||||
* @return true if we successfully linked the blackboard asset to the blackboard component.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "AI")
|
||||
bool UseBlackboard(UBlackboardData* BlackboardAsset, UBlackboardComponent*& BlackboardComponent);
|
||||
|
||||
/** does this AIController allow given UBlackboardComponent sync data with it */
|
||||
virtual bool ShouldSyncBlackboardWith(const UBlackboardComponent& OtherBlackboardComponent) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Tasks")
|
||||
void ClaimTaskResource(TSubclassOf<UGameplayTaskResource> ResourceClass);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Tasks")
|
||||
void UnclaimTaskResource(TSubclassOf<UGameplayTaskResource> ResourceClass);
|
||||
|
||||
protected:
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnUsingBlackBoard(UBlackboardComponent* BlackboardComp, UBlackboardData* BlackboardAsset);
|
||||
|
||||
virtual bool InitializeBlackboard(UBlackboardComponent& BlackboardComp, UBlackboardData& BlackboardAsset);
|
||||
|
||||
public:
|
||||
/** Retrieve the final position that controller should be looking at. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI")
|
||||
FVector GetFocalPoint() const;
|
||||
|
||||
FVector GetFocalPointForPriority(EAIFocusPriority::Type InPriority) const;
|
||||
|
||||
/** Retrieve the focal point this controller should focus to on given actor. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI")
|
||||
virtual FVector GetFocalPointOnActor(const AActor *Actor) const;
|
||||
|
||||
/** Set the position that controller should be looking at. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI", meta = (DisplayName = "SetFocalPoint", ScriptName = "SetFocalPoint", Keywords = "focus"))
|
||||
void K2_SetFocalPoint(FVector FP);
|
||||
|
||||
/** Set Focus for actor, will set FocalPoint as a result. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI", meta = (DisplayName = "SetFocus", ScriptName = "SetFocus"))
|
||||
void K2_SetFocus(AActor* NewFocus);
|
||||
|
||||
/** Get the focused actor. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI")
|
||||
AActor* GetFocusActor() const;
|
||||
|
||||
FORCEINLINE AActor* GetFocusActorForPriority(EAIFocusPriority::Type InPriority) const { return FocusInformation.Priorities.IsValidIndex(InPriority) ? FocusInformation.Priorities[InPriority].Actor.Get() : nullptr; }
|
||||
|
||||
/** Clears Focus, will also clear FocalPoint as a result */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI", meta = (DisplayName = "ClearFocus", ScriptName = "ClearFocus"))
|
||||
void K2_ClearFocus();
|
||||
|
||||
|
||||
/**
|
||||
* Computes a launch velocity vector to toss a projectile and hit the given destination.
|
||||
* Performance note: Potentially expensive. Nonzero CollisionRadius and bOnlyTraceUp=false are the more expensive options.
|
||||
*
|
||||
* @param OutTossVelocity - out param stuffed with the computed velocity to use
|
||||
* @param Start - desired start point of arc
|
||||
* @param End - desired end point of arc
|
||||
* @param TossSpeed - Initial speed of the theoretical projectile. Assumed to only change due to gravity for the entire lifetime of the projectile
|
||||
* @param CollisionSize (optional) - is the size of bounding box of the tossed actor (defaults to (0,0,0)
|
||||
* @param bOnlyTraceUp (optional) - when true collision checks verifying the arc will only be done along the upward portion of the arc
|
||||
* @return - true if a valid arc was computed, false if no valid solution could be found
|
||||
*/
|
||||
bool SuggestTossVelocity(FVector& OutTossVelocity, FVector Start, FVector End, float TossSpeed, bool bPreferHighArc, float CollisionRadius = 0, bool bOnlyTraceUp = false);
|
||||
|
||||
//~ Begin AActor Interface
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual void PostInitializeComponents() override;
|
||||
virtual void PostRegisterAllComponents() override;
|
||||
//~ End AActor Interface
|
||||
|
||||
//~ Begin AController Interface
|
||||
protected:
|
||||
virtual void OnPossess(APawn* InPawn) override;
|
||||
virtual void OnUnPossess() override;
|
||||
|
||||
public:
|
||||
virtual bool ShouldPostponePathUpdates() const override;
|
||||
virtual void DisplayDebug(UCanvas* Canvas, const FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos) override;
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
virtual void GrabDebugSnapshot(FVisualLogEntry* Snapshot) const override;
|
||||
#endif
|
||||
|
||||
virtual void Reset() override;
|
||||
|
||||
/**
|
||||
* Checks line to center and top of other actor
|
||||
* @param Other is the actor whose visibility is being checked.
|
||||
* @param ViewPoint is eye position visibility is being checked from. If vect(0,0,0) passed in, uses current viewtarget's eye position.
|
||||
* @param bAlternateChecks used only in AIController implementation
|
||||
* @return true if controller's pawn can see Other actor.
|
||||
*/
|
||||
virtual bool LineOfSightTo(const AActor* Other, FVector ViewPoint = FVector(ForceInit), bool bAlternateChecks = false) const override;
|
||||
//~ End AController Interface
|
||||
|
||||
/** Notifies AIController of changes in given actors' perception */
|
||||
virtual void ActorsPerceptionUpdated(const TArray<AActor*>& UpdatedActors);
|
||||
|
||||
/** Update direction AI is looking based on FocalPoint */
|
||||
virtual void UpdateControlRotation(float DeltaTime, bool bUpdatePawn = true);
|
||||
|
||||
/** Set FocalPoint for given priority as absolute position or offset from base. */
|
||||
virtual void SetFocalPoint(FVector NewFocus, EAIFocusPriority::Type InPriority = EAIFocusPriority::Gameplay);
|
||||
|
||||
/* Set Focus actor for given priority, will set FocalPoint as a result. */
|
||||
virtual void SetFocus(AActor* NewFocus, EAIFocusPriority::Type InPriority = EAIFocusPriority::Gameplay);
|
||||
|
||||
/** Clears Focus for given priority, will also clear FocalPoint as a result
|
||||
* @param InPriority focus priority to clear. If you don't know what to use you probably mean EAIFocusPriority::Gameplay*/
|
||||
virtual void ClearFocus(EAIFocusPriority::Type InPriority);
|
||||
|
||||
void SetPerceptionComponent(UAIPerceptionComponent& InPerceptionComponent);
|
||||
//----------------------------------------------------------------------//
|
||||
// IAIPerceptionListenerInterface
|
||||
//----------------------------------------------------------------------//
|
||||
virtual UAIPerceptionComponent* GetPerceptionComponent() override { return GetAIPerceptionComponent(); }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// INavAgentInterface
|
||||
//----------------------------------------------------------------------//
|
||||
virtual bool IsFollowingAPath() const override;
|
||||
virtual IPathFollowingAgentInterface* GetPathFollowingAgent() const override { return PathFollowingComponent; }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// IGenericTeamAgentInterface
|
||||
//----------------------------------------------------------------------//
|
||||
private:
|
||||
FGenericTeamId TeamID;
|
||||
public:
|
||||
virtual void SetGenericTeamId(const FGenericTeamId& NewTeamID) override;
|
||||
virtual FGenericTeamId GetGenericTeamId() const override { return TeamID; }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// IGameplayTaskOwnerInterface
|
||||
//----------------------------------------------------------------------//
|
||||
virtual UGameplayTasksComponent* GetGameplayTasksComponent(const UGameplayTask& Task) const override { return GetGameplayTasksComponent(); }
|
||||
virtual AActor* GetGameplayTaskOwner(const UGameplayTask* Task) const override { return const_cast<AAIController*>(this); }
|
||||
virtual AActor* GetGameplayTaskAvatar(const UGameplayTask* Task) const override { return GetPawn(); }
|
||||
virtual uint8 GetGameplayTaskDefaultPriority() const { return FGameplayTasks::DefaultPriority - 1; }
|
||||
|
||||
FORCEINLINE UGameplayTasksComponent* GetGameplayTasksComponent() const { return CachedGameplayTasksComponent; }
|
||||
|
||||
// add empty overrides to fix linker errors if project implements a child class without adding GameplayTasks module dependency
|
||||
virtual void OnGameplayTaskInitialized(UGameplayTask& Task) override {}
|
||||
virtual void OnGameplayTaskActivated(UGameplayTask& Task) override {}
|
||||
virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) override {}
|
||||
|
||||
UFUNCTION()
|
||||
virtual void OnGameplayTaskResourcesClaimed(FGameplayResourceSet NewlyClaimed, FGameplayResourceSet FreshlyReleased);
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Actions
|
||||
//----------------------------------------------------------------------//
|
||||
bool PerformAction(UPawnAction& Action, EAIRequestPriority::Type Priority, UObject* const Instigator = NULL);
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// debug/dev-time
|
||||
//----------------------------------------------------------------------//
|
||||
virtual FString GetDebugIcon() const;
|
||||
|
||||
// Cheat/debugging functions
|
||||
static void ToggleAIIgnorePlayers() { bAIIgnorePlayers = !bAIIgnorePlayers; }
|
||||
static bool AreAIIgnoringPlayers() { return bAIIgnorePlayers; }
|
||||
|
||||
/** If true, AI controllers will ignore players. */
|
||||
static bool bAIIgnorePlayers;
|
||||
|
||||
public:
|
||||
/** Returns PathFollowingComponent subobject **/
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Navigation")
|
||||
UPathFollowingComponent* GetPathFollowingComponent() const { return PathFollowingComponent; }
|
||||
/** Returns ActionsComp subobject **/
|
||||
UPawnActionsComponent* GetActionsComp() const { return ActionsComp; }
|
||||
UFUNCTION(BlueprintPure, Category = "AI|Perception")
|
||||
UAIPerceptionComponent* GetAIPerceptionComponent() { return PerceptionComponent; }
|
||||
|
||||
const UAIPerceptionComponent* GetAIPerceptionComponent() const { return PerceptionComponent; }
|
||||
|
||||
UBrainComponent* GetBrainComponent() const { return BrainComponent; }
|
||||
const UBlackboardComponent* GetBlackboardComponent() const { return Blackboard; }
|
||||
UBlackboardComponent* GetBlackboardComponent() { return Blackboard; }
|
||||
|
||||
/** Note that his function does not do any pathfollowing state transfer.
|
||||
* Intended to be called as part of initialization/setup process */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
void SetPathFollowingComponent(UPathFollowingComponent* NewPFComponent);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// forceinlines
|
||||
//----------------------------------------------------------------------//
|
||||
namespace FAISystem
|
||||
{
|
||||
FORCEINLINE bool IsValidControllerAndHasValidPawn(const AController* Controller)
|
||||
{
|
||||
return Controller != nullptr && Controller->IsPendingKillPending() == false
|
||||
&& Controller->GetPawn() != nullptr && Controller->GetPawn()->IsPendingKillPending() == false;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "AITypes.h"
|
||||
#include "AIResourceInterface.generated.h"
|
||||
|
||||
UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
|
||||
class UAIResourceInterface : public UInterface
|
||||
{
|
||||
GENERATED_UINTERFACE_BODY()
|
||||
};
|
||||
|
||||
class IAIResourceInterface
|
||||
{
|
||||
GENERATED_IINTERFACE_BODY()
|
||||
|
||||
/** If resource is lockable lock it with indicated priority */
|
||||
virtual void LockResource(EAIRequestPriority::Type LockSource) {}
|
||||
|
||||
/** clear resource lock of the given origin */
|
||||
virtual void ClearResourceLock(EAIRequestPriority::Type LockSource) {}
|
||||
|
||||
/** Force-clears all locks on resource */
|
||||
virtual void ForceUnlockResource() {}
|
||||
|
||||
/** check whether resource is currently locked */
|
||||
virtual bool IsResourceLocked() const {return false;}
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTaskResource.h"
|
||||
#include "AIResources.generated.h"
|
||||
|
||||
UCLASS(meta = (DisplayName = "AI Movement"))
|
||||
class AIMODULE_API UAIResource_Movement : public UGameplayTaskResource
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
virtual FString GenerateDebugDescription() const override;
|
||||
#endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
};
|
||||
|
||||
UCLASS(meta = (DisplayName = "AI Logic"))
|
||||
class AIMODULE_API UAIResource_Logic : public UGameplayTaskResource
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UObject/Object.h"
|
||||
#include "Tickable.h"
|
||||
#include "AISystem.h"
|
||||
#include "AISubsystem.generated.h"
|
||||
|
||||
|
||||
class UAISystem;
|
||||
|
||||
/** A class representing a common interface and behavior for AI subsystems */
|
||||
UCLASS(config = Engine, defaultconfig)
|
||||
class AIMODULE_API UAISubsystem : public UObject, public FTickableGameObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
UAISystem* AISystem;
|
||||
|
||||
public:
|
||||
UAISubsystem(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual UWorld* GetWorld() const override;
|
||||
|
||||
// FTickableGameObject begin
|
||||
virtual UWorld* GetTickableGameObjectWorld() const override { return GetWorldFast(); }
|
||||
virtual void Tick(float DeltaTime) override {}
|
||||
virtual ETickableTickType GetTickableTickType() const override;
|
||||
virtual TStatId GetStatId() const override;
|
||||
// FTickableGameObject end
|
||||
|
||||
UWorld* GetWorldFast() const { return AISystem ? AISystem->GetOuterWorld() : GetOuter()->GetWorld(); }
|
||||
};
|
||||
@@ -1,272 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/SoftObjectPath.h"
|
||||
#include "Engine/World.h"
|
||||
#include "AI/AISystemBase.h"
|
||||
#include "Math/RandomStream.h"
|
||||
#include "AISystem.generated.h"
|
||||
|
||||
class UAIAsyncTaskBlueprintProxy;
|
||||
class UAIHotSpotManager;
|
||||
class UAIPerceptionSystem;
|
||||
class UAISystem;
|
||||
class UBehaviorTreeManager;
|
||||
class UBlackboardComponent;
|
||||
class UBlackboardData;
|
||||
class UEnvQueryManager;
|
||||
class UNavLocalGridManager;
|
||||
|
||||
#define GET_AI_CONFIG_VAR(a) (GetDefault<UAISystem>()->a)
|
||||
|
||||
UCLASS(config=Engine, defaultconfig)
|
||||
class AIMODULE_API UAISystem : public UAISystemBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
/** Class that will be used to spawn the perception system, can be game-specific */
|
||||
UPROPERTY(globalconfig, EditAnywhere, Category = "AISystem", meta = (MetaClass = "AIPerceptionSystem", DisplayName = "Perception System Class"))
|
||||
FSoftClassPath PerceptionSystemClassName;
|
||||
|
||||
/** Class that will be used to spawn the hot spot manager, can be game-specific */
|
||||
UPROPERTY(globalconfig, EditAnywhere, Category = "AISystem", meta = (MetaClass = "AIHotSpotManager", DisplayName = "AIHotSpotManager Class"))
|
||||
FSoftClassPath HotSpotManagerClassName;
|
||||
|
||||
public:
|
||||
/** Default AI movement's acceptance radius used to determine whether
|
||||
* AI reached path's end */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
float AcceptanceRadius;
|
||||
|
||||
/** Value used for pathfollowing's internal code to determine whether AI reached path's point.
|
||||
* @note this value is not used for path's last point. @see AcceptanceRadius*/
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
float PathfollowingRegularPathPointAcceptanceRadius;
|
||||
|
||||
/** Similarly to PathfollowingRegularPathPointAcceptanceRadius used by pathfollowing's internals
|
||||
* but gets applied only when next point on a path represents a begining of navigation link */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
float PathfollowingNavLinkAcceptanceRadius;
|
||||
|
||||
/** If true, overlapping the goal will be counted by default as finishing a move */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
bool bFinishMoveOnGoalOverlap;
|
||||
|
||||
/** Sets default value for rather move tasks accept partial paths or not */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
bool bAcceptPartialPaths;
|
||||
|
||||
/** Sets default value for rather move tasks allow strafing or not */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Movement")
|
||||
bool bAllowStrafing;
|
||||
|
||||
/**
|
||||
* Whether or not to enable Gameplay Tasks for move tasks
|
||||
* this property is just a transition-time flag - in the end we're going to switch over to Gameplay Tasks anyway, that's the goal.
|
||||
*/
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Gameplay Tasks")
|
||||
bool bEnableBTAITasks;
|
||||
|
||||
/** if enable will make EQS not complaint about using Controllers as queriers. Default behavior (false) will
|
||||
* in places automatically convert controllers to pawns, and complain if code user bypasses the conversion or uses
|
||||
* pawn-less controller */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "EQS")
|
||||
bool bAllowControllersAsEQSQuerier;
|
||||
|
||||
/** if set, GameplayDebuggerPlugin will be loaded on module's startup */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "AISystem")
|
||||
bool bEnableDebuggerPlugin;
|
||||
|
||||
/** If set, actors will be forgotten by the perception system when their stimulus has expired.
|
||||
* If not set, the perception system will remember the actor even if they are no longer perceived and their
|
||||
* stimuli has exceeded its max age */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "AISystem")
|
||||
bool bForgetStaleActors;
|
||||
|
||||
/** If set to true will result in automatically adding the SelfActor key to new Blackboard assets. It will
|
||||
* also result in making sure all the BB assets loaded do have the SelfKey entry, via PostLoad */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "Blackboard")
|
||||
bool bAddBlackboardSelfKey = true;
|
||||
|
||||
/** Which collision channel to use for sight checks by default */
|
||||
UPROPERTY(globalconfig, EditDefaultsOnly, Category = "PerceptionSystem")
|
||||
TEnumAsByte<ECollisionChannel> DefaultSightCollisionChannel;
|
||||
|
||||
protected:
|
||||
/** Behavior tree manager used by game */
|
||||
UPROPERTY(Transient)
|
||||
UBehaviorTreeManager* BehaviorTreeManager;
|
||||
|
||||
/** Environment query manager used by game */
|
||||
UPROPERTY(Transient)
|
||||
UEnvQueryManager* EnvironmentQueryManager;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UAIPerceptionSystem* PerceptionSystem;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TArray<UAIAsyncTaskBlueprintProxy*> AllProxyObjects;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UAIHotSpotManager* HotSpotManager;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UNavLocalGridManager* NavLocalGrids;
|
||||
|
||||
typedef TMultiMap<TWeakObjectPtr<UBlackboardData>, TWeakObjectPtr<UBlackboardComponent> > FBlackboardDataToComponentsMap;
|
||||
|
||||
/** UBlackboardComponent instances that reference the blackboard data definition */
|
||||
FBlackboardDataToComponentsMap BlackboardDataToComponentsMap;
|
||||
|
||||
FDelegateHandle ActorSpawnedDelegateHandle;
|
||||
|
||||
/** random number stream to be used by all things AI. WIP */
|
||||
static FRandomStream RandomStream;
|
||||
|
||||
public:
|
||||
UAISystem(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
|
||||
// UAISystemBase begin
|
||||
virtual void InitializeActorsForPlay(bool bTimeGotReset) override;
|
||||
virtual void WorldOriginLocationChanged(FIntVector OldOriginLocation, FIntVector NewOriginLocation) override;
|
||||
virtual void CleanupWorld(bool bSessionEnded = true, bool bCleanupResources = true, UWorld* NewWorld = NULL) override;
|
||||
virtual void StartPlay() override;
|
||||
// UAISystemBase end
|
||||
|
||||
/** Behavior tree manager getter */
|
||||
FORCEINLINE UBehaviorTreeManager* GetBehaviorTreeManager() { return BehaviorTreeManager; }
|
||||
/** Behavior tree manager const getter */
|
||||
FORCEINLINE const UBehaviorTreeManager* GetBehaviorTreeManager() const { return BehaviorTreeManager; }
|
||||
|
||||
/** Environment Query manager getter */
|
||||
FORCEINLINE UEnvQueryManager* GetEnvironmentQueryManager() { return EnvironmentQueryManager; }
|
||||
/** Environment Query manager const getter */
|
||||
FORCEINLINE const UEnvQueryManager* GetEnvironmentQueryManager() const { return EnvironmentQueryManager; }
|
||||
|
||||
FORCEINLINE UAIPerceptionSystem* GetPerceptionSystem() { return PerceptionSystem; }
|
||||
FORCEINLINE const UAIPerceptionSystem* GetPerceptionSystem() const { return PerceptionSystem; }
|
||||
|
||||
FORCEINLINE UAIHotSpotManager* GetHotSpotManager() { return HotSpotManager; }
|
||||
FORCEINLINE const UAIHotSpotManager* GetHotSpotManager() const { return HotSpotManager; }
|
||||
|
||||
FORCEINLINE UNavLocalGridManager* GetNavLocalGridManager() { return NavLocalGrids; }
|
||||
FORCEINLINE const UNavLocalGridManager* GetNavLocalGridManager() const { return NavLocalGrids; }
|
||||
|
||||
FORCEINLINE static UAISystem* GetCurrentSafe(UWorld* World)
|
||||
{
|
||||
return World != nullptr ? Cast<UAISystem>(World->GetAISystem()) : NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE static UAISystem* GetCurrent(UWorld& World)
|
||||
{
|
||||
return Cast<UAISystem>(World.GetAISystem());
|
||||
}
|
||||
|
||||
FORCEINLINE UWorld* GetOuterWorld() const { return Cast<UWorld>(GetOuter()); }
|
||||
|
||||
virtual UWorld* GetWorld() const override { return GetOuterWorld(); }
|
||||
|
||||
FORCEINLINE void AddReferenceFromProxyObject(UAIAsyncTaskBlueprintProxy* BlueprintProxy) { AllProxyObjects.AddUnique(BlueprintProxy); }
|
||||
|
||||
FORCEINLINE void RemoveReferenceToProxyObject(UAIAsyncTaskBlueprintProxy* BlueprintProxy) { AllProxyObjects.RemoveSwap(BlueprintProxy); }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// cheats
|
||||
//----------------------------------------------------------------------//
|
||||
UFUNCTION(exec)
|
||||
virtual void AIIgnorePlayers();
|
||||
|
||||
UFUNCTION(exec)
|
||||
virtual void AILoggingVerbose();
|
||||
|
||||
/** insta-runs EQS query for given Target */
|
||||
void RunEQS(const FString& QueryName, UObject* Target);
|
||||
|
||||
/**
|
||||
* Iterator for traversing all UBlackboardComponent instances associated
|
||||
* with this blackboard data asset. This is a forward only iterator.
|
||||
*/
|
||||
struct FBlackboardDataToComponentsIterator
|
||||
{
|
||||
public:
|
||||
FBlackboardDataToComponentsIterator(FBlackboardDataToComponentsMap& BlackboardDataToComponentsMap, class UBlackboardData* BlackboardAsset);
|
||||
|
||||
FORCEINLINE FBlackboardDataToComponentsIterator& operator++()
|
||||
{
|
||||
++GetCurrentIteratorRef();
|
||||
TryMoveIteratorToParentBlackboard();
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE FBlackboardDataToComponentsIterator operator++(int)
|
||||
{
|
||||
FBlackboardDataToComponentsIterator Tmp(*this);
|
||||
++GetCurrentIteratorRef();
|
||||
TryMoveIteratorToParentBlackboard();
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
FORCEINLINE explicit operator bool() const { return CurrentIteratorIndex < Iterators.Num() && (bool)GetCurrentIteratorRef(); }
|
||||
FORCEINLINE bool operator !() const { return !(bool)*this; }
|
||||
|
||||
FORCEINLINE UBlackboardData* Key() const { return GetCurrentIteratorRef().Key().Get(); }
|
||||
FORCEINLINE UBlackboardComponent* Value() const { return GetCurrentIteratorRef().Value().Get(); }
|
||||
|
||||
private:
|
||||
FORCEINLINE const FBlackboardDataToComponentsMap::TConstKeyIterator& GetCurrentIteratorRef() const { return Iterators[CurrentIteratorIndex]; }
|
||||
FORCEINLINE FBlackboardDataToComponentsMap::TConstKeyIterator& GetCurrentIteratorRef() { return Iterators[CurrentIteratorIndex]; }
|
||||
|
||||
void TryMoveIteratorToParentBlackboard()
|
||||
{
|
||||
if (!GetCurrentIteratorRef() && CurrentIteratorIndex < Iterators.Num() - 1)
|
||||
{
|
||||
++CurrentIteratorIndex;
|
||||
TryMoveIteratorToParentBlackboard(); // keep incrementing until we find a valid iterator.
|
||||
}
|
||||
}
|
||||
|
||||
int32 CurrentIteratorIndex;
|
||||
|
||||
static const int32 InlineSize = 8;
|
||||
TArray<FBlackboardDataToComponentsMap::TConstKeyIterator, TInlineAllocator<InlineSize>> Iterators;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers a UBlackboardComponent instance with this blackboard data asset.
|
||||
* This will also register the component for each parent UBlackboardData
|
||||
* asset. This should be called after the component has been initialized
|
||||
* (i.e. InitializeComponent). The user is responsible for calling
|
||||
* UnregisterBlackboardComponent (i.e. UninitializeComponent).
|
||||
*/
|
||||
void RegisterBlackboardComponent(class UBlackboardData& BlackboardAsset, class UBlackboardComponent& BlackboardComp);
|
||||
|
||||
/**
|
||||
* Unregisters a UBlackboardComponent instance with this blackboard data
|
||||
* asset. This should be called before the component has been uninitialized
|
||||
* (i.e. UninitializeComponent).
|
||||
*/
|
||||
void UnregisterBlackboardComponent(class UBlackboardData& BlackboardAsset, class UBlackboardComponent& BlackboardComp);
|
||||
|
||||
/**
|
||||
* Creates a forward only iterator for that will iterate all
|
||||
* UBlackboardComponent instances that reference the specified
|
||||
* BlackboardAsset and it's parents.
|
||||
*/
|
||||
FBlackboardDataToComponentsIterator CreateBlackboardDataToComponentsIterator(class UBlackboardData& BlackboardAsset);
|
||||
|
||||
virtual void ConditionalLoadDebuggerPlugin();
|
||||
|
||||
static const FRandomStream& GetRandomStream() { return RandomStream; }
|
||||
static void SeedRandomStream(const int32 Seed) { return RandomStream.Initialize(Seed); }
|
||||
|
||||
protected:
|
||||
virtual void OnActorSpawned(AActor* SpawnedActor);
|
||||
void LoadDebuggerPlugin();
|
||||
};
|
||||
@@ -1,645 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Stats/Stats.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "NavFilters/NavigationQueryFilter.h"
|
||||
#include "AI/Navigation/NavigationTypes.h"
|
||||
#include "NavigationSystemTypes.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "AITypes.generated.h"
|
||||
|
||||
class AActor;
|
||||
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("Overall AI Time"), STAT_AI_Overall, STATGROUP_AI, AIMODULE_API);
|
||||
|
||||
#define TEXT_AI_LOCATION(v) (FAISystem::IsValidLocation(v) ? *(v).ToString() : TEXT("Invalid"))
|
||||
|
||||
namespace FAISystem
|
||||
{
|
||||
static const FRotator InvalidRotation = FRotator(FLT_MAX);
|
||||
static const FQuat InvalidOrientation = FQuat(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
static const FVector InvalidLocation = FVector(FLT_MAX);
|
||||
static const FVector InvalidDirection = FVector::ZeroVector;
|
||||
static const float InvalidRange = -1.f;
|
||||
static const float InfiniteInterval = -FLT_MAX;
|
||||
static const uint32 InvalidUnsignedID = uint32(INDEX_NONE);
|
||||
|
||||
FORCEINLINE bool IsValidLocation(const FVector& TestLocation)
|
||||
{
|
||||
return -InvalidLocation.X < TestLocation.X && TestLocation.X < InvalidLocation.X
|
||||
&& -InvalidLocation.Y < TestLocation.Y && TestLocation.Y < InvalidLocation.Y
|
||||
&& -InvalidLocation.Z < TestLocation.Z && TestLocation.Z < InvalidLocation.Z;
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsValidDirection(const FVector& TestVector)
|
||||
{
|
||||
return IsValidLocation(TestVector) == true && TestVector.IsZero() == false;
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsValidRotation(const FRotator& TestRotation)
|
||||
{
|
||||
return TestRotation != InvalidRotation;
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsValidOrientation(const FQuat& TestOrientation)
|
||||
{
|
||||
return TestOrientation != InvalidOrientation;
|
||||
}
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EAIOptionFlag
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Default,
|
||||
Enable UMETA(DisplayName = "Yes"),
|
||||
Disable UMETA(DisplayName = "No"),
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
enum class FAIDistanceType : uint8
|
||||
{
|
||||
Distance3D,
|
||||
Distance2D,
|
||||
DistanceZ,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
|
||||
namespace FAISystem
|
||||
{
|
||||
FORCEINLINE bool PickAIOption(EAIOptionFlag::Type Option, bool DefaultOption)
|
||||
{
|
||||
return Option == EAIOptionFlag::Default ? DefaultOption : (Option == EAIOptionFlag::Enable);
|
||||
}
|
||||
|
||||
FORCEINLINE EAIOptionFlag::Type BoolToAIOption(bool Value)
|
||||
{
|
||||
return Value ? EAIOptionFlag::Enable : EAIOptionFlag::Disable;
|
||||
}
|
||||
}
|
||||
|
||||
namespace EAIForceParam
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Force,
|
||||
DoNotForce,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
namespace FAIMoveFlag
|
||||
{
|
||||
static const bool StopOnOverlap = true;
|
||||
static const bool UsePathfinding = true;
|
||||
static const bool IgnorePathfinding = false;
|
||||
}
|
||||
|
||||
namespace EAILogicResuming
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Continue,
|
||||
RestartedInstead,
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EPawnActionAbortState
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NeverStarted,
|
||||
NotBeingAborted,
|
||||
/** This means waiting for child to abort before aborting self. */
|
||||
MarkPendingAbort,
|
||||
LatentAbortInProgress,
|
||||
AbortDone,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EPawnActionResult
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NotStarted,
|
||||
InProgress,
|
||||
Success,
|
||||
Failed,
|
||||
Aborted
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EPawnActionEventType
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Invalid,
|
||||
FailedToStart,
|
||||
InstantAbort,
|
||||
FinishedAborting,
|
||||
FinishedExecution,
|
||||
Push,
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EAIRequestPriority
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
/** Actions requested by Level Designers by placing AI-hinting elements on the map. */
|
||||
SoftScript,
|
||||
/** Actions AI wants to do due to its internal logic. */
|
||||
Logic,
|
||||
/** Actions LDs really want AI to perform. */
|
||||
HardScript,
|
||||
/** Actions being result of game-world mechanics, like hit reactions, death, falling, etc. In general things not depending on what AI's thinking. */
|
||||
Reaction,
|
||||
/** Ultimate priority, to be used with caution, makes AI perform given action regardless of anything else (for example disabled reactions). */
|
||||
Ultimate,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
namespace EAIRequestPriority
|
||||
{
|
||||
static const int32 Lowest = EAIRequestPriority::Logic;
|
||||
};
|
||||
|
||||
UENUM()
|
||||
namespace EAILockSource
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Animation,
|
||||
Logic,
|
||||
Script,
|
||||
Gameplay,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TCounter needs to supply following functions:
|
||||
* default constructor
|
||||
* typedef X Type; where X is an integer type to be used as ID's internal type
|
||||
* TCounter::Type GetNextAvailableID() - returns next available ID and advances the internal counter
|
||||
* uint32 GetSize() const - returns number of unique IDs created so far
|
||||
* OnIndexForced(TCounter::Type Index) - called when given Index has been force-used. Counter may need to update "next available ID"
|
||||
*/
|
||||
|
||||
template<typename TCounter>
|
||||
struct FAINamedID
|
||||
{
|
||||
const typename TCounter::Type Index;
|
||||
const FName Name;
|
||||
private:
|
||||
static AIMODULE_API TCounter Counter;
|
||||
protected:
|
||||
static TCounter& GetCounter()
|
||||
{
|
||||
return Counter;
|
||||
}
|
||||
|
||||
// back-door for forcing IDs
|
||||
FAINamedID(const FName& InName, typename TCounter::Type InIndex)
|
||||
: Index(InIndex), Name(InName)
|
||||
{
|
||||
GetCounter().OnIndexForced(InIndex);
|
||||
}
|
||||
|
||||
public:
|
||||
FAINamedID(const FName& InName)
|
||||
: Index(GetCounter().GetNextAvailableID()), Name(InName)
|
||||
{}
|
||||
|
||||
FAINamedID(const FAINamedID& Other)
|
||||
: Index(Other.Index), Name(Other.Name)
|
||||
{}
|
||||
|
||||
FAINamedID& operator=(const FAINamedID& Other)
|
||||
{
|
||||
new(this) FAINamedID(Other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FAINamedID()
|
||||
: Index(typename TCounter::Type(-1)), Name(TEXT("Invalid"))
|
||||
{}
|
||||
|
||||
operator typename TCounter::Type() const { return Index; }
|
||||
bool IsValid() const { return Index != InvalidID().Index; }
|
||||
|
||||
static uint32 GetSize() { return GetCounter().GetSize(); }
|
||||
|
||||
static FAINamedID<TCounter> InvalidID()
|
||||
{
|
||||
static const FAINamedID<TCounter> InvalidIDInstance;
|
||||
return InvalidIDInstance;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TCounter>
|
||||
struct FAIGenericID
|
||||
{
|
||||
const typename TCounter::Type Index;
|
||||
private:
|
||||
static AIMODULE_API TCounter Counter;
|
||||
protected:
|
||||
static TCounter& GetCounter()
|
||||
{
|
||||
return Counter;
|
||||
}
|
||||
|
||||
FAIGenericID(typename TCounter::Type InIndex)
|
||||
: Index(InIndex)
|
||||
{}
|
||||
|
||||
public:
|
||||
FAIGenericID(const FAIGenericID& Other)
|
||||
: Index(Other.Index)
|
||||
{}
|
||||
|
||||
FAIGenericID& operator=(const FAIGenericID& Other)
|
||||
{
|
||||
new(this) FAIGenericID(Other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FAIGenericID()
|
||||
: Index(typename TCounter::Type(-1))
|
||||
{}
|
||||
|
||||
static FAIGenericID GetNextID() { return FAIGenericID(GetCounter().GetNextAvailableID()); }
|
||||
|
||||
operator typename TCounter::Type() const { return Index; }
|
||||
bool IsValid() const { return Index != InvalidID().Index; }
|
||||
|
||||
static uint32 GetSize() { return GetCounter().GetSize(); }
|
||||
|
||||
static FAIGenericID<TCounter> InvalidID()
|
||||
{
|
||||
static const FAIGenericID<TCounter> InvalidIDInstance;
|
||||
return InvalidIDInstance;
|
||||
}
|
||||
|
||||
friend FORCEINLINE uint32 GetTypeHash(const FAIGenericID& ID)
|
||||
{
|
||||
return GetTypeHash(ID.Index);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TCounterType>
|
||||
struct FAIBasicCounter
|
||||
{
|
||||
typedef TCounterType Type;
|
||||
protected:
|
||||
Type NextAvailableID;
|
||||
public:
|
||||
FAIBasicCounter() : NextAvailableID(Type(0)) {}
|
||||
Type GetNextAvailableID() { return NextAvailableID++; }
|
||||
uint32 GetSize() const { return uint32(NextAvailableID); }
|
||||
void OnIndexForced(Type ForcedIndex) { NextAvailableID = FMath::Max<Type>(ForcedIndex + 1, NextAvailableID); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct AIMODULE_API FAIResCounter : FAIBasicCounter<uint8>
|
||||
{};
|
||||
typedef FAINamedID<FAIResCounter> FAIResourceID;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct AIMODULE_API FAIResourcesSet
|
||||
{
|
||||
static const uint32 NoResources = 0;
|
||||
static const uint32 AllResources = uint32(-1);
|
||||
static const uint8 MaxFlags = 32;
|
||||
private:
|
||||
uint32 Flags;
|
||||
public:
|
||||
FAIResourcesSet(uint32 ResourceSetDescription = NoResources) : Flags(ResourceSetDescription) {}
|
||||
FAIResourcesSet(const FAIResourceID& Resource) : Flags(0)
|
||||
{
|
||||
AddResource(Resource);
|
||||
}
|
||||
|
||||
FAIResourcesSet& AddResourceIndex(uint8 ResourceIndex) { Flags |= (1 << ResourceIndex); return *this; }
|
||||
FAIResourcesSet& RemoveResourceIndex(uint8 ResourceIndex) { Flags &= ~(1 << ResourceIndex); return *this; }
|
||||
bool ContainsResourceIndex(uint8 ResourceID) const { return (Flags & (1 << ResourceID)) != 0; }
|
||||
|
||||
FAIResourcesSet& AddResource(const FAIResourceID& Resource) { AddResourceIndex(Resource.Index); return *this; }
|
||||
FAIResourcesSet& RemoveResource(const FAIResourceID& Resource) { RemoveResourceIndex(Resource.Index); return *this; }
|
||||
bool ContainsResource(const FAIResourceID& Resource) const { return ContainsResourceIndex(Resource.Index); }
|
||||
|
||||
bool IsEmpty() const { return Flags == 0; }
|
||||
void Clear() { Flags = 0; }
|
||||
};
|
||||
|
||||
/** structure used to define which subsystem requested locking of a specific AI resource (like movement, logic, etc.) */
|
||||
struct AIMODULE_API FAIResourceLock
|
||||
{
|
||||
/** @note feel free to change the type if you need to support more then 16 lock sources */
|
||||
typedef uint16 FLockFlags;
|
||||
|
||||
FAIResourceLock();
|
||||
|
||||
void SetLock(EAIRequestPriority::Type LockPriority);
|
||||
void ClearLock(EAIRequestPriority::Type LockPriority);
|
||||
|
||||
/** set whether we should use resource lock count. clears all existing locks. */
|
||||
void SetUseResourceLockCount(bool inUseResourceLockCount);
|
||||
|
||||
/** force-clears all locks */
|
||||
void ForceClearAllLocks();
|
||||
|
||||
FORCEINLINE bool IsLocked() const
|
||||
{
|
||||
return Locks != 0;
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsLockedBy(EAIRequestPriority::Type LockPriority) const
|
||||
{
|
||||
return (Locks & (1 << LockPriority)) != 0;
|
||||
}
|
||||
|
||||
/** Answers the question if given priority is allowed to use this resource.
|
||||
* @Note that if resource is locked with priority LockPriority this function will
|
||||
* return false as well */
|
||||
FORCEINLINE bool IsAvailableFor(EAIRequestPriority::Type LockPriority) const
|
||||
{
|
||||
for (int32 Priority = EAIRequestPriority::MAX - 1; Priority >= LockPriority; --Priority)
|
||||
{
|
||||
if ((Locks & (1 << Priority)) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FString GetLockPriorityName() const;
|
||||
|
||||
void operator+=(const FAIResourceLock& Other)
|
||||
{
|
||||
Locks |= Other.Locks;
|
||||
}
|
||||
|
||||
bool operator==(const FAIResourceLock& Other)
|
||||
{
|
||||
return Locks == Other.Locks;
|
||||
}
|
||||
|
||||
private:
|
||||
TArray<uint8> ResourceLockCount;
|
||||
FLockFlags Locks;
|
||||
bool bUseResourceLockCount;
|
||||
};
|
||||
|
||||
namespace FAIResources
|
||||
{
|
||||
extern AIMODULE_API const FAIResourceID InvalidResource;
|
||||
extern AIMODULE_API const FAIResourceID Movement;
|
||||
extern AIMODULE_API const FAIResourceID Logic;
|
||||
extern AIMODULE_API const FAIResourceID Perception;
|
||||
|
||||
AIMODULE_API void RegisterResource(const FAIResourceID& Resource);
|
||||
AIMODULE_API const FAIResourceID& GetResource(int32 ResourceIndex);
|
||||
AIMODULE_API int32 GetResourcesCount();
|
||||
AIMODULE_API FString GetSetDescription(FAIResourcesSet ResourceSet);
|
||||
}
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct AIMODULE_API FAIRequestID
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
private:
|
||||
static const uint32 AnyRequestID = 0;
|
||||
static const uint32 InvalidRequestID = uint32(-1);
|
||||
|
||||
UPROPERTY()
|
||||
uint32 RequestID;
|
||||
|
||||
public:
|
||||
FAIRequestID(uint32 InRequestID = InvalidRequestID) : RequestID(InRequestID)
|
||||
{}
|
||||
|
||||
/** returns true if given ID is identical to stored ID or any of considered
|
||||
* IDs is FAIRequestID::AnyRequest*/
|
||||
FORCEINLINE bool IsEquivalent(uint32 OtherID) const
|
||||
{
|
||||
return OtherID != InvalidRequestID && this->IsValid() && (RequestID == OtherID || RequestID == AnyRequestID || OtherID == AnyRequestID);
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsEquivalent(FAIRequestID Other) const
|
||||
{
|
||||
return IsEquivalent(Other.RequestID);
|
||||
}
|
||||
|
||||
FORCEINLINE bool IsValid() const
|
||||
{
|
||||
return RequestID != InvalidRequestID;
|
||||
}
|
||||
|
||||
FORCEINLINE uint32 GetID() const { return RequestID; }
|
||||
|
||||
void operator=(uint32 OtherID)
|
||||
{
|
||||
RequestID = OtherID;
|
||||
}
|
||||
|
||||
operator uint32() const
|
||||
{
|
||||
return RequestID;
|
||||
}
|
||||
|
||||
FString ToString() const
|
||||
{
|
||||
return FString::FromInt(int32(RequestID));
|
||||
}
|
||||
|
||||
static const FAIRequestID AnyRequest;
|
||||
static const FAIRequestID CurrentRequest;
|
||||
static const FAIRequestID InvalidRequest;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UNavigationQueryFilter;
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIMoveRequest
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FAIMoveRequest();
|
||||
FAIMoveRequest(const AActor* InGoalActor);
|
||||
FAIMoveRequest(const FVector& InGoalLocation);
|
||||
|
||||
FAIMoveRequest& SetNavigationFilter(TSubclassOf<UNavigationQueryFilter> Filter) { FilterClass = Filter; return *this; }
|
||||
FAIMoveRequest& SetUsePathfinding(bool bPathfinding) { bUsePathfinding = bPathfinding; return *this; }
|
||||
FAIMoveRequest& SetAllowPartialPath(bool bAllowPartial) { bAllowPartialPath = bAllowPartial; return *this; }
|
||||
FAIMoveRequest& SetProjectGoalLocation(bool bProject) { bProjectGoalOnNavigation = bProject; return *this; }
|
||||
|
||||
FAIMoveRequest& SetCanStrafe(bool bStrafe) { bCanStrafe = bStrafe; return *this; }
|
||||
FAIMoveRequest& SetReachTestIncludesAgentRadius(bool bIncludeRadius) { bReachTestIncludesAgentRadius = bIncludeRadius; return *this; }
|
||||
FAIMoveRequest& SetReachTestIncludesGoalRadius(bool bIncludeRadius) { bReachTestIncludesGoalRadius = bIncludeRadius; return *this; }
|
||||
FAIMoveRequest& SetAcceptanceRadius(float Radius) { AcceptanceRadius = Radius; return *this; }
|
||||
FAIMoveRequest& SetUserData(const FCustomMoveSharedPtr& InUserData) { UserData = InUserData; return *this; }
|
||||
FAIMoveRequest& SetUserFlags(int32 InUserFlags) { UserFlags = InUserFlags; return *this; }
|
||||
|
||||
/** the request should be either set up to move to a location, of go to a valid actor */
|
||||
bool IsValid() const { return bInitialized && (!bMoveToActor || GoalActor); }
|
||||
|
||||
bool IsMoveToActorRequest() const { return bMoveToActor; }
|
||||
AActor* GetGoalActor() const { return bMoveToActor ? GoalActor : nullptr; }
|
||||
FVector GetGoalLocation() const { return GoalLocation; }
|
||||
/** retrieves request's requested destination location, GoalActor's location
|
||||
* or GoalLocation, depending on the request itself */
|
||||
FVector GetDestination() const { return bMoveToActor ? (GoalActor ? GoalActor->GetActorLocation() : FAISystem::InvalidLocation) : GoalLocation; }
|
||||
|
||||
bool IsUsingPathfinding() const { return bUsePathfinding; }
|
||||
bool IsUsingPartialPaths() const { return bAllowPartialPath; }
|
||||
bool IsProjectingGoal() const { return bProjectGoalOnNavigation; }
|
||||
TSubclassOf<UNavigationQueryFilter> GetNavigationFilter() const { return FilterClass; }
|
||||
|
||||
bool CanStrafe() const { return bCanStrafe; }
|
||||
bool IsReachTestIncludingAgentRadius() const { return bReachTestIncludesAgentRadius; }
|
||||
bool IsReachTestIncludingGoalRadius() const { return bReachTestIncludesGoalRadius; }
|
||||
float GetAcceptanceRadius() const { return AcceptanceRadius; }
|
||||
const FCustomMoveSharedPtr& GetUserData() const { return UserData; }
|
||||
int32 GetUserFlags() const { return UserFlags; }
|
||||
|
||||
void SetGoalActor(const AActor* InGoalActor);
|
||||
void SetGoalLocation(const FVector& InGoalLocation);
|
||||
|
||||
bool UpdateGoalLocation(const FVector& NewLocation) const;
|
||||
FString ToString() const;
|
||||
|
||||
UE_DEPRECATED(4.13, "This function is deprecated, please use SetReachTestIncludesAgentRadius instead.")
|
||||
FAIMoveRequest& SetStopOnOverlap(bool bStop);
|
||||
|
||||
UE_DEPRECATED(4.13, "This function is deprecated, please use IsReachTestIncludingAgentRadius instead.")
|
||||
bool CanStopOnOverlap() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** move goal: actor */
|
||||
UPROPERTY()
|
||||
AActor* GoalActor;
|
||||
|
||||
/** move goal: location */
|
||||
mutable FVector GoalLocation;
|
||||
|
||||
/** pathfinding: navigation filter to use */
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass;
|
||||
|
||||
/** move goal is an actor */
|
||||
uint32 bInitialized : 1;
|
||||
|
||||
/** move goal is an actor */
|
||||
uint32 bMoveToActor : 1;
|
||||
|
||||
/** pathfinding: if set - regular pathfinding will be used, if not - direct path between two points */
|
||||
uint32 bUsePathfinding : 1;
|
||||
|
||||
/** pathfinding: allow using incomplete path going toward goal but not reaching it */
|
||||
uint32 bAllowPartialPath : 1;
|
||||
|
||||
/** pathfinding: goal location will be projected on navigation data before use */
|
||||
uint32 bProjectGoalOnNavigation : 1;
|
||||
|
||||
/** pathfollowing: acceptance radius needs to be increased by agent radius (stop on overlap vs exact point) */
|
||||
uint32 bReachTestIncludesAgentRadius : 1;
|
||||
|
||||
/** pathfollowing: acceptance radius needs to be increased by goal actor radius */
|
||||
uint32 bReachTestIncludesGoalRadius : 1;
|
||||
|
||||
/** pathfollowing: keep focal point at move goal */
|
||||
uint32 bCanStrafe : 1;
|
||||
|
||||
/** pathfollowing: required distance to goal to complete move */
|
||||
float AcceptanceRadius;
|
||||
|
||||
/** custom user data: structure */
|
||||
FCustomMoveSharedPtr UserData;
|
||||
|
||||
/** custom user data: flags */
|
||||
int32 UserFlags;
|
||||
};
|
||||
|
||||
UENUM()
|
||||
enum class EGenericAICheck : uint8
|
||||
{
|
||||
Less,
|
||||
LessOrEqual,
|
||||
Equal,
|
||||
NotEqual,
|
||||
GreaterOrEqual,
|
||||
Greater,
|
||||
IsTrue,
|
||||
|
||||
MAX UMETA(Hidden)
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct FIntervalCountdown
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=Time)
|
||||
float Interval;
|
||||
|
||||
float TimeLeft;
|
||||
|
||||
explicit FIntervalCountdown(const float InInterval = -1.f) : Interval(InInterval), TimeLeft(0) {}
|
||||
|
||||
void Set(const float InNewTimeLeft)
|
||||
{
|
||||
TimeLeft = InNewTimeLeft;
|
||||
}
|
||||
|
||||
/** @return True if time's up */
|
||||
bool Tick(const float TimeDelta)
|
||||
{
|
||||
TimeLeft -= TimeDelta;
|
||||
return TimeLeft <= 0;
|
||||
}
|
||||
|
||||
/** resets the countdown back to Interval */
|
||||
void Reset()
|
||||
{
|
||||
TimeLeft = Interval;
|
||||
}
|
||||
|
||||
/** Note that this function returns meaningful results only if Interval > 0*/
|
||||
float GetElapsedTime() const
|
||||
{
|
||||
ensure(Interval > 0);
|
||||
// using -TimeLeft because at this point TimeLeft is negative
|
||||
return (Interval - TimeLeft);
|
||||
}
|
||||
|
||||
/** @return If Interval > 0 returns time accumulated since resetting. Oterwise returns FallbackValue */
|
||||
float GetElapsedTimeWithFallback(const float FallbackValue) const
|
||||
{
|
||||
return Interval > 0 ? GetElapsedTime() : FallbackValue;
|
||||
}
|
||||
};
|
||||
@@ -1,280 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "AITypes.h"
|
||||
#include "BrainComponent.h"
|
||||
#include "PawnAction.generated.h"
|
||||
|
||||
class AController;
|
||||
class APawn;
|
||||
class UPawnAction;
|
||||
class UPawnActionsComponent;
|
||||
struct FPawnActionStack;
|
||||
|
||||
UENUM()
|
||||
namespace EPawnSubActionTriggeringPolicy
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
CopyBeforeTriggering,
|
||||
ReuseInstances,
|
||||
};
|
||||
}
|
||||
|
||||
AIMODULE_API DECLARE_LOG_CATEGORY_EXTERN(LogPawnAction, Warning, All);
|
||||
DECLARE_DELEGATE_TwoParams(FPawnActionEventDelegate, UPawnAction&, EPawnActionEventType::Type);
|
||||
|
||||
UENUM()
|
||||
namespace EPawnActionFailHandling
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
RequireSuccess,
|
||||
IgnoreFailure
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Things to remember:
|
||||
* * Actions are created paused
|
||||
*/
|
||||
UCLASS(abstract, EditInlineNew)
|
||||
class AIMODULE_API UPawnAction : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
friend UPawnActionsComponent;
|
||||
friend FPawnActionStack;
|
||||
|
||||
private:
|
||||
/** Current child node executing on top of this Action */
|
||||
UPROPERTY(Transient)
|
||||
UPawnAction* ChildAction;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UPawnAction* ParentAction;
|
||||
|
||||
/** Extra reference to the component this action is being governed by */
|
||||
UPROPERTY(Transient)
|
||||
UPawnActionsComponent* OwnerComponent;
|
||||
|
||||
/** indicates an object that caused this action. Used for mass removal of actions
|
||||
* by specific object */
|
||||
UPROPERTY(Transient)
|
||||
UObject* Instigator;
|
||||
|
||||
protected:
|
||||
/** @Note: THIS IS HERE _ONLY_ BECAUSE OF THE WAY AI MESSAGING IS CURRENTLY IMPLEMENTED. WILL GO AWAY! */
|
||||
UPROPERTY(Transient)
|
||||
UBrainComponent* BrainComp;
|
||||
|
||||
private:
|
||||
/** stores registered message observers */
|
||||
TArray<FAIMessageObserverHandle> MessageHandlers;
|
||||
|
||||
EAIRequestPriority::Type ExecutionPriority;
|
||||
|
||||
FPawnActionEventDelegate ActionObserver;
|
||||
|
||||
protected:
|
||||
|
||||
FAIRequestID RequestID;
|
||||
|
||||
/** specifies which resources will be locked by this action. */
|
||||
FAIResourcesSet RequiredResources;
|
||||
|
||||
/** if this is FALSE and we're trying to push a new instance of a given class,
|
||||
* but the top of the stack is already an instance of that class ignore the attempted push */
|
||||
UPROPERTY(Category = PawnAction, EditDefaultsOnly, BlueprintReadOnly)
|
||||
uint32 bAllowNewSameClassInstance : 1;
|
||||
|
||||
/** if this is TRUE, when we try to push a new instance of an action who has the
|
||||
* same class as the action on the top of the stack, pop the one on the stack, and push the new one
|
||||
* NOTE: This trumps bAllowNewClassInstance (e.g. if this is true and bAllowNewClassInstance
|
||||
* is false the active instance will still be replaced) */
|
||||
UPROPERTY(Category = PawnAction, EditDefaultsOnly, BlueprintReadWrite)
|
||||
uint32 bReplaceActiveSameClassInstance : 1;
|
||||
|
||||
/** this is a temporary solution to allow having movement action running in background while there's
|
||||
* another action on top doing its thing
|
||||
* @note should go away once AI resource locking comes on-line */
|
||||
UPROPERTY(Category = PawnAction, EditDefaultsOnly, BlueprintReadWrite)
|
||||
uint32 bShouldPauseMovement : 1;
|
||||
|
||||
/** if set, action will call OnFinished notify even when ending as FailedToStart */
|
||||
UPROPERTY(Category = PawnAction, EditDefaultsOnly, BlueprintReadWrite, AdvancedDisplay)
|
||||
uint32 bAlwaysNotifyOnFinished : 1;
|
||||
|
||||
private:
|
||||
/** indicates whether action is in the process of abortion, and if so on what state */
|
||||
EPawnActionAbortState::Type AbortState;
|
||||
|
||||
EPawnActionResult::Type FinishResult;
|
||||
|
||||
/** Used exclusively for action events sorting */
|
||||
int32 IndexOnStack;
|
||||
|
||||
/** Indicates the action has been paused */
|
||||
uint32 bPaused : 1;
|
||||
|
||||
uint32 bHasBeenStarted : 1;
|
||||
|
||||
/** set to true when action fails the initial Start call */
|
||||
uint32 bFailedToStart : 1;
|
||||
|
||||
protected:
|
||||
/** TickAction will get called only if this flag is set. To be set in derived action's
|
||||
* constructor.
|
||||
* @NOTE Toggling at runtime is not supported */
|
||||
uint32 bWantsTick : 1;
|
||||
|
||||
public:
|
||||
|
||||
// Begin UObject
|
||||
virtual UWorld* GetWorld() const override;
|
||||
// End UObject
|
||||
|
||||
FORCEINLINE const UPawnAction* GetParentAction() const { return ParentAction; }
|
||||
FORCEINLINE const UPawnAction* GetChildAction() const { return ChildAction; }
|
||||
FORCEINLINE UPawnAction* GetChildAction() { return ChildAction; }
|
||||
FORCEINLINE bool IsPaused() const { return !!bPaused; }
|
||||
FORCEINLINE bool IsActive() const { return FinishResult == EPawnActionResult::InProgress && IsPaused() == false && AbortState == EPawnActionAbortState::NotBeingAborted; }
|
||||
FORCEINLINE bool IsBeingAborted() const { return AbortState != EPawnActionAbortState::NotBeingAborted; }
|
||||
FORCEINLINE bool IsFinished() const { return FinishResult > EPawnActionResult::InProgress; }
|
||||
FORCEINLINE bool WantsTick() const { return bWantsTick; }
|
||||
|
||||
FORCEINLINE bool ShouldPauseMovement() const { return bShouldPauseMovement; }
|
||||
|
||||
protected:
|
||||
FORCEINLINE void TickAction(float DeltaTime)
|
||||
{
|
||||
// tick ChildAction
|
||||
if (ChildAction != NULL)
|
||||
{
|
||||
ChildAction->Tick(DeltaTime);
|
||||
}
|
||||
// or self if not paused
|
||||
else if (!!bWantsTick && IsPaused() == false)
|
||||
{
|
||||
Tick(DeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/** triggers aborting of an Action
|
||||
* @param bForce
|
||||
* @return current state of task abort
|
||||
* @NOTE do not make this virtual! Contains some essential logic. */
|
||||
EPawnActionAbortState::Type Abort(EAIForceParam::Type ShouldForce = EAIForceParam::DoNotForce);
|
||||
|
||||
FORCEINLINE UPawnActionsComponent* GetOwnerComponent() { return OwnerComponent; }
|
||||
public:
|
||||
FORCEINLINE EAIRequestPriority::Type GetPriority() const { return ExecutionPriority; }
|
||||
FORCEINLINE EPawnActionResult::Type GetResult() const { return FinishResult; }
|
||||
FORCEINLINE EPawnActionAbortState::Type GetAbortState() const { return AbortState; }
|
||||
FORCEINLINE UPawnActionsComponent* GetOwnerComponent() const { return OwnerComponent; }
|
||||
FORCEINLINE UObject* GetInstigator() const { return Instigator; }
|
||||
APawn* GetPawn() const;
|
||||
AController* GetController() const;
|
||||
|
||||
template<class TActionClass>
|
||||
static TActionClass* CreateActionInstance(UWorld& World)
|
||||
{
|
||||
TSubclassOf<UPawnAction> ActionClass = TActionClass::StaticClass();
|
||||
return NewObject<TActionClass>(&World, ActionClass);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// messaging
|
||||
//----------------------------------------------------------------------//
|
||||
void WaitForMessage(FName MessageType, FAIRequestID RequestID = FAIRequestID::AnyRequest);
|
||||
// @note this function will change its signature once AI messaging is rewritten @todo
|
||||
virtual void HandleAIMessage(UBrainComponent*, const FAIMessage&){};
|
||||
|
||||
void SetActionObserver(const FPawnActionEventDelegate& InActionObserver) { ActionObserver = InActionObserver; }
|
||||
bool HasActionObserver() const { return ActionObserver.IsBound(); }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Blueprint interface
|
||||
//----------------------------------------------------------------------//
|
||||
UFUNCTION(BlueprintPure, Category = "AI|PawnActions")
|
||||
TEnumAsByte<EAIRequestPriority::Type> GetActionPriority();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|PawnActions", meta = (WorldContext="WorldContextObject"))
|
||||
static UPawnAction* CreateActionInstance(UObject* WorldContextObject, TSubclassOf<UPawnAction> ActionClass);
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// debug
|
||||
//----------------------------------------------------------------------//
|
||||
FString GetStateDescription() const;
|
||||
FString GetPriorityName() const;
|
||||
virtual FString GetDisplayName() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** starts or resumes action, depending on internal state */
|
||||
bool Activate();
|
||||
void OnPopped();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|PawnActions")
|
||||
virtual void Finish(TEnumAsByte<EPawnActionResult::Type> WithResult);
|
||||
|
||||
void SendEvent(EPawnActionEventType::Type Event);
|
||||
|
||||
void StopWaitingForMessages();
|
||||
|
||||
void SetOwnerComponent(UPawnActionsComponent* Component);
|
||||
|
||||
void SetInstigator(UObject* const InInstigator);
|
||||
|
||||
virtual void Tick(float DeltaTime);
|
||||
|
||||
/** called to start off the Action
|
||||
* @return 'true' if actions successfully started.
|
||||
* @NOTE if action fails to start no finishing or aborting mechanics will be triggered */
|
||||
virtual bool Start();
|
||||
/** called to pause action when higher priority or child action kicks in */
|
||||
virtual bool Pause(const UPawnAction* PausedBy);
|
||||
/** called to resume action after being paused */
|
||||
virtual bool Resume();
|
||||
/** called when this action is being removed from action stacks */
|
||||
virtual void OnFinished(EPawnActionResult::Type WithResult);
|
||||
/** called to give Action chance to react to child action finishing.
|
||||
* @NOTE gets called _AFTER_ child's OnFinished to give child action chance
|
||||
* to prepare "finishing data" for parent to read.
|
||||
* @NOTE clears parent-child binding */
|
||||
virtual void OnChildFinished(UPawnAction& Action, EPawnActionResult::Type WithResult);
|
||||
|
||||
/** apart from doing regular push request copies additional values from Parent, like Priority and Instigator */
|
||||
bool PushChildAction(UPawnAction& Action);
|
||||
|
||||
/** performs actual work on aborting Action. Should be called exclusively by Abort function
|
||||
* @return only valid return values here are LatendAbortInProgress and AbortDone */
|
||||
virtual EPawnActionAbortState::Type PerformAbort(EAIForceParam::Type ShouldForce) { return EPawnActionAbortState::AbortDone; }
|
||||
|
||||
FORCEINLINE bool HasBeenStarted() const { return AbortState != EPawnActionAbortState::NeverStarted; }
|
||||
|
||||
private:
|
||||
/** called when this action is put on a stack. Does not indicate action will be started soon
|
||||
* (it depends on other actions on other action stacks. Called before Start() call */
|
||||
void OnPushed();
|
||||
|
||||
/** Sets final result for this Action. To be called only once upon Action's finish */
|
||||
void SetFinishResult(EPawnActionResult::Type Result);
|
||||
|
||||
// do not un-private. Internal logic only!
|
||||
void SetAbortState(EPawnActionAbortState::Type NewAbortState);
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Blueprint inlines
|
||||
//----------------------------------------------------------------------//
|
||||
FORCEINLINE TEnumAsByte<EAIRequestPriority::Type> UPawnAction::GetActionPriority()
|
||||
{
|
||||
return ExecutionPriority;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "PawnAction_BlueprintBase.generated.h"
|
||||
|
||||
class APawn;
|
||||
|
||||
UCLASS(abstract, Blueprintable)
|
||||
class AIMODULE_API UPawnAction_BlueprintBase : public UPawnAction
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Blueprint interface
|
||||
//----------------------------------------------------------------------//
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "AI|PawnActions")
|
||||
void ActionStart(APawn* ControlledPawn);
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "AI|PawnActions")
|
||||
void ActionTick(APawn* ControlledPawn, float DeltaSeconds);
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "AI|PawnActions")
|
||||
void ActionPause(APawn* ControlledPawn);
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "AI|PawnActions")
|
||||
void ActionResume(APawn* ControlledPawn);
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "AI|PawnActions")
|
||||
void ActionFinished(APawn* ControlledPawn, EPawnActionResult::Type WithResult);
|
||||
|
||||
protected:
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual bool Start() override;
|
||||
virtual bool Pause(const UPawnAction* PausedBy) override;
|
||||
virtual bool Resume() override;
|
||||
virtual void OnFinished(EPawnActionResult::Type WithResult) override;
|
||||
};
|
||||
@@ -1,122 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "NavFilters/NavigationQueryFilter.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "Navigation/PathFollowingComponent.h"
|
||||
#include "PawnAction_Move.generated.h"
|
||||
|
||||
class AAIController;
|
||||
|
||||
UENUM()
|
||||
namespace EPawnActionMoveMode
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
UsePathfinding,
|
||||
StraightLine,
|
||||
};
|
||||
}
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UPawnAction_Move : public UPawnAction
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
protected:
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadWrite)
|
||||
AActor* GoalActor;
|
||||
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadWrite)
|
||||
FVector GoalLocation;
|
||||
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, meta = (ClampMin = "0.01"), BlueprintReadWrite)
|
||||
float AcceptableRadius;
|
||||
|
||||
/** "None" will result in default filter being used */
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadWrite)
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass;
|
||||
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadWrite)
|
||||
uint32 bAllowStrafe : 1;
|
||||
|
||||
/** if set to true (default) will make action succeed when the pawn's collision component overlaps with goal's collision component */
|
||||
UPROPERTY()
|
||||
uint32 bFinishOnOverlap : 1;
|
||||
|
||||
/** if set, movement will use path finding */
|
||||
UPROPERTY()
|
||||
uint32 bUsePathfinding : 1;
|
||||
|
||||
/** if set, use incomplete path when goal can't be reached */
|
||||
UPROPERTY()
|
||||
uint32 bAllowPartialPath : 1;
|
||||
|
||||
/** if set, GoalLocation will be projected on navigation before using */
|
||||
UPROPERTY()
|
||||
uint32 bProjectGoalToNavigation : 1;
|
||||
|
||||
/** if set, path to GoalActor will be updated with goal's movement */
|
||||
UPROPERTY()
|
||||
uint32 bUpdatePathToGoal : 1;
|
||||
|
||||
/** if set, other actions with the same priority will be aborted when path is changed */
|
||||
UPROPERTY()
|
||||
uint32 bAbortChildActionOnPathChange : 1;
|
||||
|
||||
public:
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
static UPawnAction_Move* CreateAction(UWorld& World, AActor* GoalActor, EPawnActionMoveMode::Type Mode);
|
||||
static UPawnAction_Move* CreateAction(UWorld& World, const FVector& GoalLocation, EPawnActionMoveMode::Type Mode);
|
||||
|
||||
static bool CheckAlreadyAtGoal(AAIController& Controller, const FVector& TestLocation, float Radius);
|
||||
static bool CheckAlreadyAtGoal(AAIController& Controller, const AActor& TestGoal, float Radius);
|
||||
|
||||
virtual void HandleAIMessage(UBrainComponent*, const FAIMessage&) override;
|
||||
|
||||
void SetPath(FNavPathSharedRef InPath);
|
||||
virtual void OnPathUpdated(FNavigationPath* UpdatedPath, ENavPathEvent::Type Event);
|
||||
|
||||
void SetAcceptableRadius(float NewAcceptableRadius) { AcceptableRadius = NewAcceptableRadius; }
|
||||
void SetFinishOnOverlap(bool bNewFinishOnOverlap) { bFinishOnOverlap = bNewFinishOnOverlap; }
|
||||
void EnableStrafing(bool bNewStrafing) { bAllowStrafe = bNewStrafing; }
|
||||
void EnablePathUpdateOnMoveGoalLocationChange(bool bEnable) { bUpdatePathToGoal = bEnable; }
|
||||
void EnableGoalLocationProjectionToNavigation(bool bEnable) { bProjectGoalToNavigation = bEnable; }
|
||||
void EnableChildAbortionOnPathUpdate(bool bEnable) { bAbortChildActionOnPathChange = bEnable; }
|
||||
void SetFilterClass(TSubclassOf<UNavigationQueryFilter> NewFilterClass) { FilterClass = NewFilterClass; }
|
||||
void SetAllowPartialPath(bool bEnable) { bAllowPartialPath = bEnable; }
|
||||
|
||||
protected:
|
||||
/** currently followed path */
|
||||
FNavPathSharedPtr Path;
|
||||
|
||||
FDelegateHandle PathObserverDelegateHandle;
|
||||
|
||||
/** Handle for efficient management of DeferredPerformMoveAction timer */
|
||||
FTimerHandle TimerHandle_DeferredPerformMoveAction;
|
||||
|
||||
/** Handle for efficient management of TryToRepath timer */
|
||||
FTimerHandle TimerHandle_TryToRepath;
|
||||
|
||||
void ClearPath();
|
||||
virtual bool Start() override;
|
||||
virtual bool Pause(const UPawnAction* PausedBy) override;
|
||||
virtual bool Resume() override;
|
||||
virtual void OnFinished(EPawnActionResult::Type WithResult) override;
|
||||
virtual EPawnActionAbortState::Type PerformAbort(EAIForceParam::Type ShouldForce) override;
|
||||
virtual bool IsPartialPathAllowed() const;
|
||||
|
||||
virtual EPathFollowingRequestResult::Type RequestMove(AAIController& Controller);
|
||||
|
||||
bool PerformMoveAction();
|
||||
void DeferredPerformMoveAction();
|
||||
|
||||
void TryToRepath();
|
||||
void ClearPendingRepath();
|
||||
void ClearTimers();
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "PawnAction_Repeat.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UPawnAction_Repeat : public UPawnAction
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
enum
|
||||
{
|
||||
LoopForever = -1
|
||||
};
|
||||
|
||||
/** Action to repeat. This instance won't really be run, it's a source for copying actions to be actually performed */
|
||||
UPROPERTY()
|
||||
UPawnAction* ActionToRepeat;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UPawnAction* RecentActionCopy;
|
||||
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadOnly)
|
||||
TEnumAsByte<EPawnActionFailHandling::Type> ChildFailureHandlingMode;
|
||||
|
||||
int32 RepeatsLeft;
|
||||
|
||||
EPawnSubActionTriggeringPolicy::Type SubActionTriggeringPolicy;
|
||||
|
||||
/** @param NumberOfRepeats number of times to repeat action. UPawnAction_Repeat::LoopForever loops forever */
|
||||
static UPawnAction_Repeat* CreateAction(UWorld& World, UPawnAction* ActionToRepeat, int32 NumberOfRepeats, EPawnSubActionTriggeringPolicy::Type InSubActionTriggeringPolicy = EPawnSubActionTriggeringPolicy::CopyBeforeTriggering);
|
||||
|
||||
protected:
|
||||
virtual bool Start() override;
|
||||
virtual bool Resume() override;
|
||||
virtual void OnChildFinished(UPawnAction& Action, EPawnActionResult::Type WithResult) override;
|
||||
|
||||
bool PushSubAction();
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "PawnAction_Sequence.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UPawnAction_Sequence : public UPawnAction
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UPawnAction*> ActionSequence;
|
||||
|
||||
UPROPERTY(Category = PawnAction, EditAnywhere, BlueprintReadOnly)
|
||||
TEnumAsByte<EPawnActionFailHandling::Type> ChildFailureHandlingMode;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UPawnAction* RecentActionCopy;
|
||||
|
||||
uint32 CurrentActionIndex;
|
||||
|
||||
EPawnSubActionTriggeringPolicy::Type SubActionTriggeringPolicy;
|
||||
|
||||
static UPawnAction_Sequence* CreateAction(UWorld& World, TArray<UPawnAction*>& ActionSequence, EPawnSubActionTriggeringPolicy::Type InSubActionTriggeringPolicy = EPawnSubActionTriggeringPolicy::CopyBeforeTriggering);
|
||||
|
||||
protected:
|
||||
virtual bool Start() override;
|
||||
virtual bool Resume() override;
|
||||
virtual void OnChildFinished(UPawnAction& Action, EPawnActionResult::Type WithResult) override;
|
||||
|
||||
bool PushNextActionCopy();
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "PawnAction_Wait.generated.h"
|
||||
|
||||
/** uses system timers rather then ticking */
|
||||
UCLASS()
|
||||
class AIMODULE_API UPawnAction_Wait : public UPawnAction
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
float TimeToWait;
|
||||
|
||||
float FinishTimeStamp;
|
||||
|
||||
FTimerHandle TimerHandle;
|
||||
|
||||
/** InTimeToWait < 0 (or just FAISystem::InfiniteInterval) will result in waiting forever */
|
||||
static UPawnAction_Wait* CreateAction(UWorld& World, float InTimeToWait = FAISystem::InfiniteInterval);
|
||||
|
||||
virtual bool Start() override;
|
||||
virtual bool Pause(const UPawnAction* PausedBy) override;
|
||||
virtual bool Resume() override;
|
||||
virtual EPawnActionAbortState::Type PerformAbort(EAIForceParam::Type ShouldForce) override;
|
||||
|
||||
void TimerDone();
|
||||
};
|
||||
@@ -1,178 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "Actions/PawnAction.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "PawnActionsComponent.generated.h"
|
||||
|
||||
class AController;
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FPawnActionEvent
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
// used for marking FPawnActionEvent instances created solely for comparisons uses
|
||||
static const int32 FakeActionIndex = INDEX_NONE;
|
||||
|
||||
UPROPERTY()
|
||||
UPawnAction* Action;
|
||||
|
||||
EPawnActionEventType::Type EventType;
|
||||
|
||||
EAIRequestPriority::Type Priority;
|
||||
|
||||
// used to maintain order of equally-important messages
|
||||
uint32 Index;
|
||||
|
||||
FPawnActionEvent() : Action(NULL), EventType(EPawnActionEventType::Invalid), Priority(EAIRequestPriority::MAX), Index(uint32(-1))
|
||||
{}
|
||||
|
||||
FPawnActionEvent(UPawnAction& Action, EPawnActionEventType::Type EventType, uint32 Index);
|
||||
|
||||
bool operator==(const FPawnActionEvent& Other) const { return (Action == Other.Action) && (EventType == Other.EventType) && (Priority == Other.Priority); }
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FPawnActionStack
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FPawnActionStack()
|
||||
: TopAction(nullptr)
|
||||
{}
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
UPawnAction* TopAction;
|
||||
|
||||
public:
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
/** All it does is tie actions into a double-linked list making NewTopAction
|
||||
* new stack's top */
|
||||
void PushAction(UPawnAction& NewTopAction);
|
||||
|
||||
/** Looks through the double-linked action list looking for specified action
|
||||
* and if found action will be popped along with all it's siblings */
|
||||
void PopAction(UPawnAction& ActionToPop);
|
||||
|
||||
FORCEINLINE UPawnAction* GetTop() const { return TopAction; }
|
||||
|
||||
FORCEINLINE bool IsEmpty() const { return TopAction == NULL; }
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Debugging-testing purposes
|
||||
//----------------------------------------------------------------------//
|
||||
int32 GetStackSize() const;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UPawnActionsComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
UPROPERTY(BlueprintReadOnly, Category="PawnActions")
|
||||
APawn* ControlledPawn;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<FPawnActionStack> ActionStacks;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<FPawnActionEvent> ActionEvents;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
UPawnAction* CurrentAction;
|
||||
|
||||
/** set when logic was locked by hi priority stack */
|
||||
uint32 bLockedAILogic : 1;
|
||||
|
||||
private:
|
||||
uint32 ActionEventIndex;
|
||||
|
||||
public:
|
||||
//----------------------------------------------------------------------//
|
||||
// UActorComponent
|
||||
//----------------------------------------------------------------------//
|
||||
virtual void OnUnregister() override;
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// blueprint interface
|
||||
//----------------------------------------------------------------------//
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|PawnActions", meta = (DisplayName = "PerformAction", ScriptName = "PerformAction"))
|
||||
static bool K2_PerformAction(APawn* Pawn, UPawnAction* Action, TEnumAsByte<EAIRequestPriority::Type> Priority = EAIRequestPriority::HardScript);
|
||||
static bool PerformAction(APawn& Pawn, UPawnAction& Action, TEnumAsByte<EAIRequestPriority::Type> Priority = EAIRequestPriority::HardScript);
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
//
|
||||
//----------------------------------------------------------------------//
|
||||
/** Use it to save component work to figure out what it's controlling
|
||||
* or if component can't/won't be able to figure it out properly
|
||||
* @NOTE will throw a log warning if trying to set ControlledPawn if it's already set */
|
||||
void SetControlledPawn(APawn* NewPawn);
|
||||
FORCEINLINE APawn* GetControlledPawn() { return ControlledPawn; }
|
||||
FORCEINLINE const APawn* GetControlledPawn() const { return ControlledPawn; }
|
||||
FORCEINLINE AController* GetController() { return ControlledPawn ? ControlledPawn->GetController() : NULL; }
|
||||
FORCEINLINE UPawnAction* GetCurrentAction() { return CurrentAction; }
|
||||
|
||||
bool OnEvent(UPawnAction& Action, EPawnActionEventType::Type Event);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = PawnAction, meta = (DisplayName = "PushAction", ScriptName = "PushAction"))
|
||||
bool K2_PushAction(UPawnAction* NewAction, EAIRequestPriority::Type Priority, UObject* Instigator = NULL);
|
||||
bool PushAction(UPawnAction& NewAction, EAIRequestPriority::Type Priority, UObject* Instigator = NULL);
|
||||
|
||||
/** Aborts given action instance */
|
||||
UFUNCTION(BlueprintCallable, Category = PawnAction, meta = (DisplayName = "AbortAction", ScriptName = "AbortAction"))
|
||||
EPawnActionAbortState::Type K2_AbortAction(UPawnAction* ActionToAbort);
|
||||
EPawnActionAbortState::Type AbortAction(UPawnAction& ActionToAbort);
|
||||
|
||||
/** Aborts given action instance */
|
||||
UFUNCTION(BlueprintCallable, Category = PawnAction, meta = (DisplayName = "ForceAbortAction", ScriptName = "ForceAbortAction"))
|
||||
EPawnActionAbortState::Type K2_ForceAbortAction(UPawnAction* ActionToAbort);
|
||||
EPawnActionAbortState::Type ForceAbortAction(UPawnAction& ActionToAbort);
|
||||
|
||||
/** removes all actions instigated with Priority by Instigator
|
||||
* @param Priority if equal to EAIRequestPriority::MAX then all priority queues will be searched.
|
||||
* This is less efficient so use with caution
|
||||
* @return number of action abortions requested (performed asyncronously) */
|
||||
uint32 AbortActionsInstigatedBy(UObject* const Instigator, EAIRequestPriority::Type Priority);
|
||||
|
||||
void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
FORCEINLINE UPawnAction* GetActiveAction(EAIRequestPriority::Type Priority) const { return ActionStacks[Priority].GetTop(); }
|
||||
bool HasActiveActionOfType(EAIRequestPriority::Type Priority, TSubclassOf<UPawnAction> PawnActionClass) const;
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
void DescribeSelfToVisLog(struct FVisualLogEntry* Snapshot) const;
|
||||
#endif // ENABLE_VISUAL_LOG
|
||||
|
||||
static FString DescribeEventType(EPawnActionEventType::Type EventType);
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// Debugging-testing purposes
|
||||
//----------------------------------------------------------------------//
|
||||
int32 GetActionStackSize(EAIRequestPriority::Type Priority) const { return ActionStacks[Priority].GetStackSize(); }
|
||||
int32 GetActionEventsQueueSize() const { return ActionEvents.Num(); }
|
||||
|
||||
protected:
|
||||
/** Finds the action that should be running. If it's different from CurrentAction
|
||||
* then CurrentAction gets paused and newly selected action gets started up */
|
||||
void UpdateCurrentAction();
|
||||
|
||||
APawn* CacheControlledPawn();
|
||||
|
||||
void UpdateAILogicLock();
|
||||
|
||||
private:
|
||||
/** Removed all pending action events associated with PawnAction. Private to make sure it's called only in special cases */
|
||||
void RemoveEventsForAction(UPawnAction& PawnAction);
|
||||
};
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTNode.h"
|
||||
#include "BTAuxiliaryNode.generated.h"
|
||||
|
||||
struct FBTAuxiliaryMemory : public FBTInstancedNodeMemory
|
||||
{
|
||||
float NextTickRemainingTime;
|
||||
float AccumulatedDeltaTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Auxiliary nodes are supporting nodes, that receive notification about execution flow and can be ticked
|
||||
*
|
||||
* Because some of them can be instanced for specific AI, following virtual functions are not marked as const:
|
||||
* - OnBecomeRelevant
|
||||
* - OnCeaseRelevant
|
||||
* - TickNode
|
||||
*
|
||||
* If your node is not being instanced (default behavior), DO NOT change any properties of object within those functions!
|
||||
* Template nodes are shared across all behavior tree components using the same tree asset and must store
|
||||
* their runtime properties in provided NodeMemory block (allocation size determined by GetInstanceMemorySize() )
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTAuxiliaryNode : public UBTNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** wrapper for node instancing: OnBecomeRelevant */
|
||||
void WrappedOnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** wrapper for node instancing: OnCeaseRelevant */
|
||||
void WrappedOnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** wrapper for node instancing: TickNode
|
||||
* @param OwnerComp The behavior tree owner of this node
|
||||
* @param NodeMemory The instance memory of the current node
|
||||
* @param DeltaSeconds DeltaTime since last call
|
||||
* @param NextNeededDeltaTime In out parameter, if this node needs a smaller DeltaTime it is his responsibility to change it
|
||||
* @returns True if it actually done some processing or false if it was skipped because of not ticking or in between time interval */
|
||||
bool WrappedTickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds, float& NextNeededDeltaTime) const;
|
||||
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual uint16 GetSpecialMemorySize() const override;
|
||||
|
||||
/** fill in data about tree structure */
|
||||
void InitializeParentLink(uint8 InChildIndex);
|
||||
|
||||
/** @return parent task node */
|
||||
const UBTNode* GetMyNode() const;
|
||||
|
||||
/** @return index of child in parent's array or MAX_uint8 */
|
||||
uint8 GetChildIndex() const;
|
||||
|
||||
/** Get The next needed deltatime for this node
|
||||
* @param OwnerComp The behavior tree owner of this node
|
||||
* @param NodeMemory The instance memory of the current node
|
||||
* @return The next needed DeltaTime */
|
||||
float GetNextNeededDeltaTime(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, OnBecomeRelevant will be used */
|
||||
uint8 bNotifyBecomeRelevant:1;
|
||||
|
||||
/** if set, OnCeaseRelevant will be used */
|
||||
uint8 bNotifyCeaseRelevant:1;
|
||||
|
||||
/** if set, OnTick will be used */
|
||||
uint8 bNotifyTick : 1;
|
||||
|
||||
/** if set, conditional tick will use remaining time form node's memory */
|
||||
uint8 bTickIntervals : 1;
|
||||
|
||||
/** child index in parent node */
|
||||
uint8 ChildIndex;
|
||||
|
||||
/** called when auxiliary node becomes active
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
|
||||
/** called when auxiliary node becomes inactive
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
|
||||
/** tick function
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds);
|
||||
|
||||
/** sets next tick time */
|
||||
void SetNextTickTime(uint8* NodeMemory, float RemainingTime) const;
|
||||
|
||||
/** gets remaining time for next tick */
|
||||
float GetNextTickRemainingTime(uint8* NodeMemory) const;
|
||||
};
|
||||
|
||||
FORCEINLINE uint8 UBTAuxiliaryNode::GetChildIndex() const
|
||||
{
|
||||
return ChildIndex;
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTNode.h"
|
||||
#include "BTCompositeNode.generated.h"
|
||||
|
||||
class UBTCompositeNode;
|
||||
class UBTDecorator;
|
||||
class UBTService;
|
||||
class UBTTaskNode;
|
||||
|
||||
DECLARE_DELEGATE_RetVal_ThreeParams(int32, FGetNextChildDelegate, FBehaviorTreeSearchData& /*search data*/, int32 /*last child index*/, EBTNodeResult::Type /*last result*/);
|
||||
|
||||
struct FBTCompositeMemory
|
||||
{
|
||||
/** index of currently active child node */
|
||||
int8 CurrentChild;
|
||||
|
||||
/** child override for next selection */
|
||||
int8 OverrideChild;
|
||||
};
|
||||
|
||||
UENUM()
|
||||
enum class EBTChildIndex : uint8
|
||||
{
|
||||
FirstNode,
|
||||
TaskNode,
|
||||
};
|
||||
|
||||
UENUM()
|
||||
namespace EBTDecoratorLogic
|
||||
{
|
||||
// keep in sync with DescribeLogicOp() in BTCompositeNode.cpp
|
||||
|
||||
enum Type
|
||||
{
|
||||
Invalid,
|
||||
/** Test decorator conditions. */
|
||||
Test,
|
||||
/** logic op: AND */
|
||||
And,
|
||||
/** logic op: OR */
|
||||
Or,
|
||||
/** logic op: NOT */
|
||||
Not,
|
||||
};
|
||||
}
|
||||
|
||||
USTRUCT()
|
||||
struct FBTDecoratorLogic
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
TEnumAsByte<EBTDecoratorLogic::Type> Operation;
|
||||
|
||||
UPROPERTY()
|
||||
uint16 Number;
|
||||
|
||||
FBTDecoratorLogic() : Operation(EBTDecoratorLogic::Invalid), Number(0) {}
|
||||
FBTDecoratorLogic(uint8 InOperation, uint16 InNumber) : Operation(InOperation), Number(InNumber) {}
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct FBTCompositeChild
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
/** child node */
|
||||
UPROPERTY()
|
||||
UBTCompositeNode* ChildComposite;
|
||||
|
||||
UPROPERTY()
|
||||
UBTTaskNode* ChildTask;
|
||||
|
||||
/** execution decorators */
|
||||
UPROPERTY()
|
||||
TArray<UBTDecorator*> Decorators;
|
||||
|
||||
/** logic operations for decorators */
|
||||
UPROPERTY()
|
||||
TArray<FBTDecoratorLogic> DecoratorOps;
|
||||
};
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTCompositeNode : public UBTNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** child nodes */
|
||||
UPROPERTY()
|
||||
TArray<FBTCompositeChild> Children;
|
||||
|
||||
/** service nodes */
|
||||
UPROPERTY()
|
||||
TArray<UBTService*> Services;
|
||||
|
||||
/** delegate for finding next child to execute */
|
||||
UE_DEPRECATED(4.21, "OnNextChild is no longer being used. Please override UBTCompositeNode::GetNextChildHandler instead")
|
||||
FGetNextChildDelegate OnNextChild;
|
||||
|
||||
~UBTCompositeNode();
|
||||
|
||||
/** fill in data about tree structure */
|
||||
void InitializeComposite(uint16 InLastExecutionIndex);
|
||||
|
||||
/** find next child branch to execute */
|
||||
int32 FindChildToExecute(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& LastResult) const;
|
||||
|
||||
/** get index of child node (handle subtrees) */
|
||||
int32 GetChildIndex(FBehaviorTreeSearchData& SearchData, const UBTNode& ChildNode) const;
|
||||
/** get index of child node */
|
||||
int32 GetChildIndex(const UBTNode& ChildNode) const;
|
||||
|
||||
/** called before passing search to child node */
|
||||
void OnChildActivation(FBehaviorTreeSearchData& SearchData, const UBTNode& ChildNode) const;
|
||||
void OnChildActivation(FBehaviorTreeSearchData& SearchData, int32 ChildIndex) const;
|
||||
|
||||
/** called after child has finished search */
|
||||
void OnChildDeactivation(FBehaviorTreeSearchData& SearchData, const UBTNode& ChildNode, EBTNodeResult::Type& NodeResult) const;
|
||||
void OnChildDeactivation(FBehaviorTreeSearchData& SearchData, int32 ChildIndex, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** called when start enters this node */
|
||||
void OnNodeActivation(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
/** called when search leaves this node */
|
||||
void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** called when search needs to reactivate this node */
|
||||
void OnNodeRestart(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
/** notify about task execution start */
|
||||
void ConditionalNotifyChildExecution(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, const UBTNode& ChildNode, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** size of instance memory */
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
|
||||
/** @return child node at given index */
|
||||
UBTNode* GetChildNode(int32 Index) const;
|
||||
|
||||
/** @return children count */
|
||||
int32 GetChildrenNum() const;
|
||||
|
||||
/** @return execution index of child node */
|
||||
uint16 GetChildExecutionIndex(int32 Index, EBTChildIndex ChildMode = EBTChildIndex::TaskNode) const;
|
||||
|
||||
/** @return execution index of last node in child branches */
|
||||
uint16 GetLastExecutionIndex() const;
|
||||
|
||||
/** set override for next child index */
|
||||
virtual void SetChildOverride(FBehaviorTreeSearchData& SearchData, int8 Index) const;
|
||||
|
||||
/** gathers description of all runtime parameters */
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
|
||||
/** check if child node can execute new subtree */
|
||||
virtual bool CanPushSubtree(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, int32 ChildIdx) const;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** @return allowed flow abort modes for decorators */
|
||||
virtual bool CanAbortLowerPriority() const;
|
||||
virtual bool CanAbortSelf() const;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
/** find branch containing specified node index */
|
||||
int32 GetMatchingChildIndex(int32 ActiveInstanceIdx, FBTNodeIndex& NodeIdx) const;
|
||||
|
||||
/** get first execution index of given branch */
|
||||
uint16 GetBranchExecutionIndex(uint16 NodeInBranchIdx) const;
|
||||
|
||||
/** is child execution allowed by decorators? */
|
||||
bool DoDecoratorsAllowExecution(UBehaviorTreeComponent& OwnerComp, int32 InstanceIdx, int32 ChildIdx) const;
|
||||
|
||||
bool IsApplyingDecoratorScope() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, all decorators in branch below will be removed when execution flow leaves (decorators on this node are not affected) */
|
||||
UPROPERTY(EditAnywhere, Category = Composite)
|
||||
uint32 bApplyDecoratorScope : 1;
|
||||
|
||||
/** if set, NotifyChildExecution will be called */
|
||||
uint32 bUseChildExecutionNotify : 1;
|
||||
|
||||
/** if set, NotifyNodeActivation will be called */
|
||||
uint32 bUseNodeActivationNotify : 1;
|
||||
|
||||
/** if set, NotifyNodeDeactivation will be called */
|
||||
uint32 bUseNodeDeactivationNotify : 1;
|
||||
|
||||
/** if set, CanNotifyDecoratorsOnActivation will be called */
|
||||
uint32 bUseDecoratorsActivationCheck : 1;
|
||||
|
||||
/** if set, CanNotifyDecoratorsOnDeactivation will be called */
|
||||
uint32 bUseDecoratorsDeactivationCheck : 1;
|
||||
|
||||
/** if set, CanNotifyDecoratorsOnFailedActivation will be called */
|
||||
uint32 bUseDecoratorsFailedActivationCheck : 1;
|
||||
|
||||
/** execution index of last node in child branches */
|
||||
uint16 LastExecutionIndex;
|
||||
|
||||
/** called just after child execution, allows to modify result */
|
||||
virtual void NotifyChildExecution(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** called when start enters this node */
|
||||
virtual void NotifyNodeActivation(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
/** called when start leaves this node */
|
||||
virtual void NotifyNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** check if NotifyDecoratorsOnActivation is allowed, requires bUseDecoratorsActivationCheck flag */
|
||||
virtual bool CanNotifyDecoratorsOnActivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx) const;
|
||||
|
||||
/** check if NotifyDecoratorsOnDeactivation is allowed, requires bUseDecoratorsDeactivationCheck flag */
|
||||
virtual bool CanNotifyDecoratorsOnDeactivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** check if NotifyDecoratorsOnFailedActivation is allowed, requires bUseDecoratorsActivationCheck flag */
|
||||
virtual bool CanNotifyDecoratorsOnFailedActivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** runs through decorators on given child node and notify them about activation */
|
||||
void NotifyDecoratorsOnActivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx) const;
|
||||
|
||||
/** runs through decorators on given child node and notify them about deactivation */
|
||||
void NotifyDecoratorsOnDeactivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** runs through decorators on given child node and notify them about failed activation */
|
||||
void NotifyDecoratorsOnFailedActivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** get next child to process and store it in CurrentChild */
|
||||
int32 GetNextChild(FBehaviorTreeSearchData& SearchData, int32 LastChildIdx, EBTNodeResult::Type LastResult) const;
|
||||
|
||||
/** store delayed execution request */
|
||||
void RequestDelayedExecution(UBehaviorTreeComponent& OwnerComp, EBTNodeResult::Type LastResult) const;
|
||||
|
||||
protected:
|
||||
virtual int32 GetNextChildHandler(struct FBehaviorTreeSearchData& SearchData, int32 PrevChild, EBTNodeResult::Type LastResult) const { return BTSpecialChild::ReturnToParent; }
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE UBTNode* UBTCompositeNode::GetChildNode(int32 Index) const
|
||||
{
|
||||
return Children.IsValidIndex(Index) ?
|
||||
(Children[Index].ChildComposite ?
|
||||
(UBTNode*)Children[Index].ChildComposite :
|
||||
(UBTNode*)Children[Index].ChildTask) :
|
||||
nullptr;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 UBTCompositeNode::GetChildrenNum() const
|
||||
{
|
||||
return Children.Num();
|
||||
}
|
||||
|
||||
FORCEINLINE uint16 UBTCompositeNode::GetLastExecutionIndex() const
|
||||
{
|
||||
return LastExecutionIndex;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBTCompositeNode::IsApplyingDecoratorScope() const
|
||||
{
|
||||
return bApplyDecoratorScope;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTAuxiliaryNode.h"
|
||||
#include "BTDecorator.generated.h"
|
||||
|
||||
class FBehaviorDecoratorDetails;
|
||||
|
||||
enum class EBTDecoratorAbortRequest : uint8
|
||||
{
|
||||
// request execution update when only result of condition changes and active branch of tree can potentially change too
|
||||
ConditionResultChanged,
|
||||
|
||||
// request execution update every time as long as condition is still passing
|
||||
ConditionPassing,
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorators are supporting nodes placed on parent-child connection, that receive notification about execution flow and can be ticked
|
||||
*
|
||||
* Because some of them can be instanced for specific AI, following virtual functions are not marked as const:
|
||||
* - OnNodeActivation
|
||||
* - OnNodeDeactivation
|
||||
* - OnNodeProcessed
|
||||
* - OnBecomeRelevant (from UBTAuxiliaryNode)
|
||||
* - OnCeaseRelevant (from UBTAuxiliaryNode)
|
||||
* - TickNode (from UBTAuxiliaryNode)
|
||||
*
|
||||
* If your node is not being instanced (default behavior), DO NOT change any properties of object within those functions!
|
||||
* Template nodes are shared across all behavior tree components using the same tree asset and must store
|
||||
* their runtime properties in provided NodeMemory block (allocation size determined by GetInstanceMemorySize() )
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTDecorator : public UBTAuxiliaryNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** wrapper for node instancing: CalculateRawConditionValue */
|
||||
bool WrappedCanExecute(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** wrapper for node instancing: OnNodeActivation */
|
||||
void WrappedOnNodeActivation(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
/** wrapper for node instancing: OnNodeDeactivation */
|
||||
void WrappedOnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) const;
|
||||
|
||||
/** wrapper for node instancing: OnNodeProcessed */
|
||||
void WrappedOnNodeProcessed(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult) const;
|
||||
|
||||
/** @return flow controller's abort mode */
|
||||
EBTFlowAbortMode::Type GetFlowAbortMode() const;
|
||||
|
||||
/** @return true if condition should be inversed */
|
||||
bool IsInversed() const;
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
/** modify current flow abort mode, so it can be used with parent composite */
|
||||
void UpdateFlowAbortMode();
|
||||
|
||||
/** @return true if current abort mode can be used with parent composite */
|
||||
bool IsFlowAbortModeValid() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, FlowAbortMode can be set to None */
|
||||
uint32 bAllowAbortNone : 1;
|
||||
|
||||
/** if set, FlowAbortMode can be set to LowerPriority and Both */
|
||||
uint32 bAllowAbortLowerPri : 1;
|
||||
|
||||
/** if set, FlowAbortMode can be set to Self and Both */
|
||||
uint32 bAllowAbortChildNodes : 1;
|
||||
|
||||
/** if set, OnNodeActivation will be used */
|
||||
uint32 bNotifyActivation : 1;
|
||||
|
||||
/** if set, OnNodeDeactivation will be used */
|
||||
uint32 bNotifyDeactivation : 1;
|
||||
|
||||
/** if set, OnNodeProcessed will be used */
|
||||
uint32 bNotifyProcessed : 1;
|
||||
|
||||
/** if set, static description will include default description of inversed condition */
|
||||
uint32 bShowInverseConditionDesc : 1;
|
||||
|
||||
private:
|
||||
/** if set, condition check result will be inversed */
|
||||
UPROPERTY(Category = Condition, EditAnywhere)
|
||||
uint32 bInverseCondition : 1;
|
||||
|
||||
protected:
|
||||
/** flow controller settings */
|
||||
UPROPERTY(Category=FlowControl, EditAnywhere)
|
||||
TEnumAsByte<EBTFlowAbortMode::Type> FlowAbortMode;
|
||||
|
||||
void SetIsInversed(bool bShouldBeInversed);
|
||||
|
||||
/** called when underlying node is activated
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnNodeActivation(FBehaviorTreeSearchData& SearchData);
|
||||
|
||||
/** called when underlying node has finished
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult);
|
||||
|
||||
/** called when underlying node was processed (deactivated or failed to activate)
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnNodeProcessed(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult);
|
||||
|
||||
/** calculates raw, core value of decorator's condition. Should not include calling IsInversed */
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** more "flow aware" version of calling RequestExecution(this) on owning behavior tree component
|
||||
* should be used in external events that may change result of CalculateRawConditionValue
|
||||
*/
|
||||
void ConditionalFlowAbort(UBehaviorTreeComponent& OwnerComp, EBTDecoratorAbortRequest RequestMode) const;
|
||||
|
||||
friend FBehaviorDecoratorDetails;
|
||||
|
||||
//----------------------------------------------------------------------//
|
||||
// DEPRECATED
|
||||
//----------------------------------------------------------------------//
|
||||
UE_DEPRECATED(4.12, "This function is deprecated, please use InitializeParentLink instead.")
|
||||
void InitializeDecorator(uint8 InChildIndex);
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE EBTFlowAbortMode::Type UBTDecorator::GetFlowAbortMode() const
|
||||
{
|
||||
return FlowAbortMode;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBTDecorator::IsInversed() const
|
||||
{
|
||||
return bInverseCondition;
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "BTFunctionLibrary.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UBehaviorTreeComponent;
|
||||
class UBlackboardComponent;
|
||||
class UBTNode;
|
||||
|
||||
namespace FBTNodeBPImplementationHelper
|
||||
{
|
||||
static const int32 NoImplementation = 0;
|
||||
static const int32 Generic = 1 << 0;
|
||||
static const int32 AISpecific = 1 << 1;
|
||||
static const int32 All = Generic | AISpecific;
|
||||
|
||||
/** checks if given object implements GenericEventName and/or AIEventName BP events, and returns an result as flags set on return integer
|
||||
* @return flags set in returned integer indicate kinds of events implemented by given object */
|
||||
AIMODULE_API int32 CheckEventImplementationVersion(FName GenericEventName, FName AIEventName, const UObject& Object, const UClass& StopAtClass);
|
||||
|
||||
UE_DEPRECATED(4.11, "This version of CheckEventImplementationVersion is deprecated. Please use the one taking reference to UObject and StopAtClass rather than a pointers.")
|
||||
AIMODULE_API int32 CheckEventImplementationVersion(FName GenericEventName, FName AIEventName, const UObject* Ob, const UClass* StopAtClass);
|
||||
}
|
||||
|
||||
UCLASS(meta=(RestrictedToClasses="BTNode"))
|
||||
class AIMODULE_API UBTFunctionLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static UBlackboardComponent* GetOwnersBlackboard(UBTNode* NodeOwner);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static UBehaviorTreeComponent* GetOwnerComponent(UBTNode* NodeOwner);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static UObject* GetBlackboardValueAsObject(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static AActor* GetBlackboardValueAsActor(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static UClass* GetBlackboardValueAsClass(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static uint8 GetBlackboardValueAsEnum(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static int32 GetBlackboardValueAsInt(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static float GetBlackboardValueAsFloat(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static bool GetBlackboardValueAsBool(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static FString GetBlackboardValueAsString(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static FName GetBlackboardValueAsName(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static FVector GetBlackboardValueAsVector(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category ="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static FRotator GetBlackboardValueAsRotator(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsObject(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, UObject* Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsClass(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, UClass* Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsEnum(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, uint8 Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsInt(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, int32 Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsFloat(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, float Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsBool(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, bool Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsString(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, FString Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsName(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, FName Value);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
|
||||
static void SetBlackboardValueAsVector(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, FVector Value);
|
||||
|
||||
/** (DEPRECATED) Use ClearBlackboardValue instead */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner", DeprecatedFunction, DeprecationMessage="Use ClearBlackboardValue instead."))
|
||||
static void ClearBlackboardValueAsVector(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta = (HidePin = "NodeOwner", DefaultToSelf = "NodeOwner"))
|
||||
static void SetBlackboardValueAsRotator(UBTNode* NodeOwner, const FBlackboardKeySelector& Key, FRotator Value);
|
||||
|
||||
/** Resets indicated value to "not set" value, based on values type */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta = (HidePin = "NodeOwner", DefaultToSelf = "NodeOwner"))
|
||||
static void ClearBlackboardValue(UBTNode* NodeOwner, const FBlackboardKeySelector& Key);
|
||||
|
||||
/** Initialize variables marked as "instance memory" and set owning actor for blackboard operations */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner", DeprecatedFunction, DeprecationMessage="No longer needed"))
|
||||
static void StartUsingExternalEvent(UBTNode* NodeOwner, AActor* OwningActor);
|
||||
|
||||
/** Save variables marked as "instance memory" and clear owning actor */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner", DeprecatedFunction, DeprecationMessage="No longer needed"))
|
||||
static void StopUsingExternalEvent(UBTNode* NodeOwner);
|
||||
};
|
||||
@@ -1,327 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BehaviorTreeComponent.h"
|
||||
#include "BehaviorTree/BlackboardAssetProvider.h"
|
||||
#include "GameplayTaskOwnerInterface.h"
|
||||
#include "Tasks/AITask.h"
|
||||
#include "BTNode.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UBehaviorTree;
|
||||
class UBlackboardData;
|
||||
class UBTCompositeNode;
|
||||
class UGameplayTasksComponent;
|
||||
|
||||
AIMODULE_API DECLARE_LOG_CATEGORY_EXTERN(LogBehaviorTree, Display, All);
|
||||
|
||||
class AAIController;
|
||||
class UWorld;
|
||||
class UBehaviorTree;
|
||||
class UBehaviorTreeComponent;
|
||||
class UBTCompositeNode;
|
||||
class UBlackboardData;
|
||||
struct FBehaviorTreeSearchData;
|
||||
|
||||
struct FBTInstancedNodeMemory
|
||||
{
|
||||
int32 NodeIdx;
|
||||
};
|
||||
|
||||
UCLASS(Abstract,config=Game)
|
||||
class AIMODULE_API UBTNode : public UObject, public IGameplayTaskOwnerInterface
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual UWorld* GetWorld() const override;
|
||||
|
||||
/** fill in data about tree structure */
|
||||
void InitializeNode(UBTCompositeNode* InParentNode, uint16 InExecutionIndex, uint16 InMemoryOffset, uint8 InTreeDepth);
|
||||
|
||||
/** initialize any asset related data */
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset);
|
||||
|
||||
/** initialize memory block */
|
||||
virtual void InitializeMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryInit::Type InitType) const;
|
||||
|
||||
/** cleanup memory block */
|
||||
virtual void CleanupMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryClear::Type CleanupType) const;
|
||||
|
||||
/** gathers description of all runtime parameters */
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const;
|
||||
|
||||
/** size of instance memory */
|
||||
virtual uint16 GetInstanceMemorySize() const;
|
||||
|
||||
/** called when node instance is added to tree */
|
||||
virtual void OnInstanceCreated(UBehaviorTreeComponent& OwnerComp);
|
||||
|
||||
/** called when node instance is removed from tree */
|
||||
virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp);
|
||||
|
||||
/** called on creating subtree to set up memory and instancing */
|
||||
void InitializeInSubtree(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, int32& NextInstancedIndex, EBTMemoryInit::Type InitType) const;
|
||||
|
||||
/** called on removing subtree to cleanup memory */
|
||||
void CleanupInSubtree(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryClear::Type CleanupType) const;
|
||||
|
||||
/** size of special, hidden memory block for internal mechanics */
|
||||
virtual uint16 GetSpecialMemorySize() const;
|
||||
|
||||
#if USE_BEHAVIORTREE_DEBUGGER
|
||||
/** fill in data about execution order */
|
||||
void InitializeExecutionOrder(UBTNode* NextNode);
|
||||
|
||||
/** @return next node in execution order */
|
||||
UBTNode* GetNextNode() const;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
T* GetNodeMemory(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
template<typename T>
|
||||
const T* GetNodeMemory(const FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
template<typename T>
|
||||
T* GetNodeMemory(FBehaviorTreeInstance& BTInstance) const;
|
||||
|
||||
template<typename T>
|
||||
const T* GetNodeMemory(const FBehaviorTreeInstance& BTInstance) const;
|
||||
|
||||
template<typename T>
|
||||
T* CastInstanceNodeMemory(uint8* NodeMemory) const;
|
||||
|
||||
/** get special memory block used for hidden shared data (e.g. node instancing) */
|
||||
template<typename T>
|
||||
T* GetSpecialNodeMemory(uint8* NodeMemory) const;
|
||||
|
||||
/** @return parent node */
|
||||
UBTCompositeNode* GetParentNode() const;
|
||||
|
||||
/** @return name of node */
|
||||
FString GetNodeName() const;
|
||||
|
||||
/** @return execution index */
|
||||
uint16 GetExecutionIndex() const;
|
||||
|
||||
/** @return memory offset */
|
||||
uint16 GetMemoryOffset() const;
|
||||
|
||||
/** @return depth in tree */
|
||||
uint8 GetTreeDepth() const;
|
||||
|
||||
/** sets bIsInjected flag, do NOT call this function unless you really know what you are doing! */
|
||||
void MarkInjectedNode();
|
||||
|
||||
/** @return true if node was injected by subtree */
|
||||
bool IsInjected() const;
|
||||
|
||||
/** sets bCreateNodeInstance flag, do NOT call this function on already pushed tree instance! */
|
||||
void ForceInstancing(bool bEnable);
|
||||
|
||||
/** @return true if node wants to be instanced */
|
||||
bool HasInstance() const;
|
||||
|
||||
/** @return true if this object is instanced node */
|
||||
bool IsInstanced() const;
|
||||
|
||||
/** @return tree asset */
|
||||
UBehaviorTree* GetTreeAsset() const;
|
||||
|
||||
/** @return blackboard asset */
|
||||
UBlackboardData* GetBlackboardAsset() const;
|
||||
|
||||
/** @return node instance if bCreateNodeInstance was set */
|
||||
UBTNode* GetNodeInstance(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
UBTNode* GetNodeInstance(FBehaviorTreeSearchData& SearchData) const;
|
||||
|
||||
/** @return string containing description of this node instance with all relevant runtime values */
|
||||
FString GetRuntimeDescription(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity) const;
|
||||
|
||||
/** @return string containing description of this node with all setup values */
|
||||
virtual FString GetStaticDescription() const;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** Get the name of the icon used to display this node in the editor */
|
||||
virtual FName GetNodeIconName() const;
|
||||
|
||||
/** Get whether this node is using a blueprint for its logic */
|
||||
virtual bool UsesBlueprint() const;
|
||||
|
||||
/** Called after creating new node in behavior tree editor, use for versioning */
|
||||
virtual void OnNodeCreated() {}
|
||||
#endif
|
||||
|
||||
/** Gets called only for instanced nodes(bCreateNodeInstance == true). In practive overridden by BP-implemented BT nodes */
|
||||
virtual void SetOwner(AActor* ActorOwner) {}
|
||||
|
||||
// BEGIN IGameplayTaskOwnerInterface
|
||||
virtual UGameplayTasksComponent* GetGameplayTasksComponent(const UGameplayTask& Task) const override;
|
||||
virtual AActor* GetGameplayTaskOwner(const UGameplayTask* Task) const override;
|
||||
virtual AActor* GetGameplayTaskAvatar(const UGameplayTask* Task) const override;
|
||||
virtual uint8 GetGameplayTaskDefaultPriority() const override;
|
||||
virtual void OnGameplayTaskInitialized(UGameplayTask& Task) override;
|
||||
// END IGameplayTaskOwnerInterface
|
||||
|
||||
UBehaviorTreeComponent* GetBTComponentForTask(UGameplayTask& Task) const;
|
||||
|
||||
template <class T>
|
||||
T* NewBTAITask(UBehaviorTreeComponent& BTComponent)
|
||||
{
|
||||
check(BTComponent.GetAIOwner());
|
||||
bOwnsGameplayTasks = true;
|
||||
return UAITask::NewAITask<T>(*BTComponent.GetAIOwner(), *this, TEXT("Behavior"));
|
||||
}
|
||||
|
||||
/** node name */
|
||||
UPROPERTY(Category=Description, EditAnywhere)
|
||||
FString NodeName;
|
||||
|
||||
private:
|
||||
|
||||
/** source asset */
|
||||
UPROPERTY()
|
||||
UBehaviorTree* TreeAsset;
|
||||
|
||||
/** parent node */
|
||||
UPROPERTY()
|
||||
UBTCompositeNode* ParentNode;
|
||||
|
||||
#if USE_BEHAVIORTREE_DEBUGGER
|
||||
/** next node in execution order */
|
||||
UBTNode* NextExecutionNode;
|
||||
#endif
|
||||
|
||||
/** depth first index (execution order) */
|
||||
uint16 ExecutionIndex;
|
||||
|
||||
/** instance memory offset */
|
||||
uint16 MemoryOffset;
|
||||
|
||||
/** depth in tree */
|
||||
uint8 TreeDepth;
|
||||
|
||||
/** set automatically for node instances. Should never be set manually */
|
||||
uint8 bIsInstanced : 1;
|
||||
|
||||
/** if set, node is injected by subtree. Should never be set manually */
|
||||
uint8 bIsInjected : 1;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, node will be instanced instead of using memory block and template shared with all other BT components */
|
||||
uint8 bCreateNodeInstance : 1;
|
||||
|
||||
/** set to true if task owns any GameplayTasks. Note this requires tasks to be created via NewBTAITask
|
||||
* Otherwise specific BT task node class is responsible for ending the gameplay tasks on node finish */
|
||||
uint8 bOwnsGameplayTasks : 1;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE UBehaviorTree* UBTNode::GetTreeAsset() const
|
||||
{
|
||||
return TreeAsset;
|
||||
}
|
||||
|
||||
FORCEINLINE UBTCompositeNode* UBTNode::GetParentNode() const
|
||||
{
|
||||
return ParentNode;
|
||||
}
|
||||
|
||||
#if USE_BEHAVIORTREE_DEBUGGER
|
||||
FORCEINLINE UBTNode* UBTNode::GetNextNode() const
|
||||
{
|
||||
return NextExecutionNode;
|
||||
}
|
||||
#endif
|
||||
|
||||
FORCEINLINE uint16 UBTNode::GetExecutionIndex() const
|
||||
{
|
||||
return ExecutionIndex;
|
||||
}
|
||||
|
||||
FORCEINLINE uint16 UBTNode::GetMemoryOffset() const
|
||||
{
|
||||
return MemoryOffset;
|
||||
}
|
||||
|
||||
FORCEINLINE uint8 UBTNode::GetTreeDepth() const
|
||||
{
|
||||
return TreeDepth;
|
||||
}
|
||||
|
||||
FORCEINLINE void UBTNode::MarkInjectedNode()
|
||||
{
|
||||
bIsInjected = true;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBTNode::IsInjected() const
|
||||
{
|
||||
return bIsInjected;
|
||||
}
|
||||
|
||||
FORCEINLINE void UBTNode::ForceInstancing(bool bEnable)
|
||||
{
|
||||
// allow only in not initialized trees, side effect: root node always blocked
|
||||
check(ParentNode == NULL);
|
||||
|
||||
bCreateNodeInstance = bEnable;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBTNode::HasInstance() const
|
||||
{
|
||||
return bCreateNodeInstance;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBTNode::IsInstanced() const
|
||||
{
|
||||
return bIsInstanced;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* UBTNode::GetNodeMemory(FBehaviorTreeSearchData& SearchData) const
|
||||
{
|
||||
return GetNodeMemory<T>(SearchData.OwnerComp.InstanceStack[SearchData.OwnerComp.GetActiveInstanceIdx()]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* UBTNode::GetNodeMemory(const FBehaviorTreeSearchData& SearchData) const
|
||||
{
|
||||
return GetNodeMemory<T>(SearchData.OwnerComp.InstanceStack[SearchData.OwnerComp.GetActiveInstanceIdx()]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* UBTNode::GetNodeMemory(FBehaviorTreeInstance& BTInstance) const
|
||||
{
|
||||
return (T*)(BTInstance.GetInstanceMemory().GetData() + MemoryOffset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T* UBTNode::GetNodeMemory(const FBehaviorTreeInstance& BTInstance) const
|
||||
{
|
||||
return (const T*)(BTInstance.GetInstanceMemory().GetData() + MemoryOffset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* UBTNode::CastInstanceNodeMemory(uint8* NodeMemory) const
|
||||
{
|
||||
// using '<=' rather than '==' to allow child classes to extend parent's
|
||||
// memory class as well (which would make GetInstanceMemorySize return
|
||||
// a value equal or greater to sizeof(T)).
|
||||
checkf(sizeof(T) <= GetInstanceMemorySize(), TEXT("Requesting type of %zu bytes but GetInstanceMemorySize returns %u. Make sure GetInstanceMemorySize is implemented properly in %s class hierarchy."), sizeof(T), GetInstanceMemorySize(), *GetFName().ToString());
|
||||
return reinterpret_cast<T*>(NodeMemory);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* UBTNode::GetSpecialNodeMemory(uint8* NodeMemory) const
|
||||
{
|
||||
const int32 SpecialMemorySize = GetSpecialMemorySize();
|
||||
return SpecialMemorySize ? (T*)(NodeMemory - ((SpecialMemorySize + 3) & ~3)) : nullptr;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTAuxiliaryNode.h"
|
||||
#include "BTService.generated.h"
|
||||
|
||||
/**
|
||||
* Behavior Tree service nodes is designed to perform "background" tasks that update AI's knowledge.
|
||||
*
|
||||
* Services are being executed when underlying branch of behavior tree becomes active,
|
||||
* but unlike tasks they don't return any results and can't directly affect execution flow.
|
||||
*
|
||||
* Usually they perform periodical checks (see TickNode) and often store results in blackboard.
|
||||
* If any decorator node below requires results of check beforehand, use OnSearchStart function.
|
||||
* Keep in mind that any checks performed there have to be instantaneous!
|
||||
*
|
||||
* Other typical use case is creating a marker when specific branch is being executed
|
||||
* (see OnBecomeRelevant, OnCeaseRelevant), by setting a flag in blackboard.
|
||||
*
|
||||
* Because some of them can be instanced for specific AI, following virtual functions are not marked as const:
|
||||
* - OnBecomeRelevant (from UBTAuxiliaryNode)
|
||||
* - OnCeaseRelevant (from UBTAuxiliaryNode)
|
||||
* - TickNode (from UBTAuxiliaryNode)
|
||||
* - OnSearchStart
|
||||
*
|
||||
* If your node is not being instanced (default behavior), DO NOT change any properties of object within those functions!
|
||||
* Template nodes are shared across all behavior tree components using the same tree asset and must store
|
||||
* their runtime properties in provided NodeMemory block (allocation size determined by GetInstanceMemorySize() )
|
||||
*/
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTService : public UBTAuxiliaryNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
void NotifyParentActivation(FBehaviorTreeSearchData& SearchData);
|
||||
|
||||
protected:
|
||||
|
||||
// Gets the description of our tick interval
|
||||
FString GetStaticTickIntervalDescription() const;
|
||||
|
||||
// Gets the description for our service
|
||||
virtual FString GetStaticServiceDescription() const;
|
||||
|
||||
/** defines time span between subsequent ticks of the service */
|
||||
UPROPERTY(Category=Service, EditAnywhere, meta=(ClampMin="0.001"))
|
||||
float Interval;
|
||||
|
||||
/** adds random range to service's Interval */
|
||||
UPROPERTY(Category=Service, EditAnywhere, meta=(ClampMin="0.0"))
|
||||
float RandomDeviation;
|
||||
|
||||
/** call Tick event when task search enters this node (SearchStart will be called as well) */
|
||||
UPROPERTY(Category = Service, EditAnywhere, AdvancedDisplay)
|
||||
uint32 bCallTickOnSearchStart : 1;
|
||||
|
||||
/** if set, next tick time will be always reset to service's interval when node is activated */
|
||||
UPROPERTY(Category = Service, EditAnywhere, AdvancedDisplay)
|
||||
uint32 bRestartTimerOnEachActivation : 1;
|
||||
|
||||
/** if set, service will be notified about search entering underlying branch */
|
||||
uint32 bNotifyOnSearch : 1;
|
||||
|
||||
/** update next tick interval
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
|
||||
/** called when search enters underlying branch
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnSearchStart(FBehaviorTreeSearchData& SearchData);
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
/** set next tick time */
|
||||
virtual void ScheduleNextTick(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
};
|
||||
@@ -1,117 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTNode.h"
|
||||
#include "BTTaskNode.generated.h"
|
||||
|
||||
class UBTService;
|
||||
|
||||
/**
|
||||
* Task are leaf nodes of behavior tree, which perform actual actions
|
||||
*
|
||||
* Because some of them can be instanced for specific AI, following virtual functions are not marked as const:
|
||||
* - ExecuteTask
|
||||
* - AbortTask
|
||||
* - TickTask
|
||||
* - OnMessage
|
||||
*
|
||||
* If your node is not being instanced (default behavior), DO NOT change any properties of object within those functions!
|
||||
* Template nodes are shared across all behavior tree components using the same tree asset and must store
|
||||
* their runtime properties in provided NodeMemory block (allocation size determined by GetInstanceMemorySize() )
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTTaskNode : public UBTNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** starts this task, should return Succeeded, Failed or InProgress
|
||||
* (use FinishLatentTask() when returning InProgress)
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
|
||||
protected:
|
||||
/** aborts this task, should return Aborted or InProgress
|
||||
* (use FinishLatentAbort() when returning InProgress)
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
|
||||
public:
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) override;
|
||||
|
||||
/** message observer's hook */
|
||||
void ReceivedMessage(UBrainComponent* BrainComp, const FAIMessage& Message);
|
||||
|
||||
/** wrapper for node instancing: ExecuteTask */
|
||||
EBTNodeResult::Type WrappedExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** wrapper for node instancing: AbortTask */
|
||||
EBTNodeResult::Type WrappedAbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
|
||||
/** wrapper for node instancing: TickTask
|
||||
* @param OwnerComp The behavior tree owner of this node
|
||||
* @param NodeMemory The instance memory of the current node
|
||||
* @param DeltaSeconds DeltaTime since last call
|
||||
* @param NextNeededDeltaTime In out parameter, if this node needs a smaller DeltaTime it is his responsibility to change it
|
||||
* @returns True if it actually done some processing or false if it was skipped because of not ticking or in between time interval */
|
||||
bool WrappedTickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds, float& NextNeededDeltaTime) const;
|
||||
|
||||
/** wrapper for node instancing: OnTaskFinished */
|
||||
void WrappedOnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) const;
|
||||
|
||||
/** helper function: finish latent executing */
|
||||
void FinishLatentTask(UBehaviorTreeComponent& OwnerComp, EBTNodeResult::Type TaskResult) const;
|
||||
|
||||
/** helper function: finishes latent aborting */
|
||||
void FinishLatentAbort(UBehaviorTreeComponent& OwnerComp) const;
|
||||
|
||||
/** @return true if task search should be discarded when this task is selected to execute but is already running */
|
||||
bool ShouldIgnoreRestartSelf() const;
|
||||
|
||||
/** service nodes */
|
||||
UPROPERTY()
|
||||
TArray<UBTService*> Services;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, task search will be discarded when this task is selected to execute but is already running */
|
||||
UPROPERTY(EditAnywhere, Category=Task)
|
||||
uint32 bIgnoreRestartSelf : 1;
|
||||
|
||||
/** if set, TickTask will be called */
|
||||
uint32 bNotifyTick : 1;
|
||||
|
||||
/** if set, OnTaskFinished will be called */
|
||||
uint32 bNotifyTaskFinished : 1;
|
||||
|
||||
/** ticks this task
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds);
|
||||
|
||||
/** message handler, default implementation will finish latent execution/abortion
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnMessage(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, FName Message, int32 RequestID, bool bSuccess);
|
||||
|
||||
/** called when task execution is finished
|
||||
* this function should be considered as const (don't modify state of object) if node is not instanced! */
|
||||
virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult);
|
||||
|
||||
/** register message observer */
|
||||
void WaitForMessage(UBehaviorTreeComponent& OwnerComp, FName MessageType) const;
|
||||
void WaitForMessage(UBehaviorTreeComponent& OwnerComp, FName MessageType, int32 RequestID) const;
|
||||
|
||||
/** unregister message observers */
|
||||
void StopWaitingForMessages(UBehaviorTreeComponent& OwnerComp) const;
|
||||
};
|
||||
|
||||
FORCEINLINE bool UBTTaskNode::ShouldIgnoreRestartSelf() const
|
||||
{
|
||||
return bIgnoreRestartSelf;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "BehaviorTree/BTCompositeNode.h"
|
||||
#include "BehaviorTree.generated.h"
|
||||
|
||||
class UBlackboardData;
|
||||
class UBTDecorator;
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class AIMODULE_API UBehaviorTree : public UObject, public IBlackboardAssetProvider
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** root node of loaded tree */
|
||||
UPROPERTY()
|
||||
UBTCompositeNode* RootNode;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
/** Graph for Behavior Tree */
|
||||
UPROPERTY()
|
||||
class UEdGraph* BTGraph;
|
||||
|
||||
/** Info about the graphs we last edited */
|
||||
UPROPERTY()
|
||||
TArray<FEditedDocumentInfo> LastEditedDocuments;
|
||||
|
||||
#endif
|
||||
|
||||
// BEGIN IBlackboardAssetProvider
|
||||
/** @return blackboard asset */
|
||||
virtual UBlackboardData* GetBlackboardAsset() const override;
|
||||
// END IBlackboardAssetProvider
|
||||
|
||||
/** blackboard asset for this tree */
|
||||
UPROPERTY()
|
||||
UBlackboardData* BlackboardAsset;
|
||||
|
||||
/** root level decorators, used by subtrees */
|
||||
UPROPERTY()
|
||||
TArray<UBTDecorator*> RootDecorators;
|
||||
|
||||
/** logic operators for root level decorators, used by subtrees */
|
||||
UPROPERTY()
|
||||
TArray<FBTDecoratorLogic> RootDecoratorOps;
|
||||
|
||||
/** memory size required for instance of this tree */
|
||||
uint16 InstanceMemorySize;
|
||||
};
|
||||
@@ -1,481 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "AITypes.h"
|
||||
#include "BrainComponent.h"
|
||||
#include "ProfilingDebugging/CsvProfiler.h"
|
||||
#include "BehaviorTreeComponent.generated.h"
|
||||
|
||||
class FBehaviorTreeDebugger;
|
||||
class UBehaviorTree;
|
||||
class UBTAuxiliaryNode;
|
||||
class UBTCompositeNode;
|
||||
class UBTDecorator;
|
||||
class UBTNode;
|
||||
class UBTTask_RunBehavior;
|
||||
class UBTTask_RunBehaviorDynamic;
|
||||
class UBTTaskNode;
|
||||
struct FScopedBehaviorTreeLock;
|
||||
|
||||
struct FBTNodeExecutionInfo
|
||||
{
|
||||
/** index of first task allowed to be executed */
|
||||
FBTNodeIndex SearchStart;
|
||||
|
||||
/** index of last task allowed to be executed */
|
||||
FBTNodeIndex SearchEnd;
|
||||
|
||||
/** node to be executed */
|
||||
UBTCompositeNode* ExecuteNode;
|
||||
|
||||
/** subtree index */
|
||||
uint16 ExecuteInstanceIdx;
|
||||
|
||||
/** result used for resuming execution */
|
||||
TEnumAsByte<EBTNodeResult::Type> ContinueWithResult;
|
||||
|
||||
/** if set, tree will try to execute next child of composite instead of forcing branch containing SearchStart */
|
||||
uint8 bTryNextChild : 1;
|
||||
|
||||
/** if set, request was not instigated by finishing task/initialization but is a restart (e.g. decorator) */
|
||||
uint8 bIsRestart : 1;
|
||||
|
||||
FBTNodeExecutionInfo() : ExecuteNode(NULL), bTryNextChild(false), bIsRestart(false) { }
|
||||
};
|
||||
|
||||
struct FBTPendingExecutionInfo
|
||||
{
|
||||
/** next task to execute */
|
||||
UBTTaskNode* NextTask;
|
||||
|
||||
/** if set, tree ran out of nodes */
|
||||
uint32 bOutOfNodes : 1;
|
||||
|
||||
/** if set, request can't be executed */
|
||||
uint32 bLocked : 1;
|
||||
|
||||
FBTPendingExecutionInfo() : NextTask(NULL), bOutOfNodes(false), bLocked(false) {}
|
||||
bool IsSet() const { return (NextTask || bOutOfNodes) && !bLocked; }
|
||||
bool IsLocked() const { return bLocked; }
|
||||
|
||||
void Lock() { bLocked = true; }
|
||||
void Unlock() { bLocked = false; }
|
||||
};
|
||||
|
||||
struct FBTPendingAuxNodesUnregisterInfo
|
||||
{
|
||||
/** list of node index ranges pending aux nodes unregistration */
|
||||
TArray<FBTNodeIndexRange> Ranges;
|
||||
};
|
||||
|
||||
struct FBTTreeStartInfo
|
||||
{
|
||||
UBehaviorTree* Asset;
|
||||
EBTExecutionMode::Type ExecuteMode;
|
||||
uint8 bPendingInitialize : 1;
|
||||
|
||||
FBTTreeStartInfo() : Asset(nullptr), ExecuteMode(EBTExecutionMode::Looped), bPendingInitialize(0) {}
|
||||
bool IsSet() const { return Asset != nullptr; }
|
||||
bool HasPendingInitialize() const { return bPendingInitialize && IsSet(); }
|
||||
};
|
||||
|
||||
UCLASS(ClassGroup = AI, meta = (BlueprintSpawnableComponent))
|
||||
class AIMODULE_API UBehaviorTreeComponent : public UBrainComponent
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
// UActorComponent overrides
|
||||
virtual void RegisterComponentTickFunctions(bool bRegister) override;
|
||||
virtual void SetComponentTickEnabled(bool bEnabled) override;
|
||||
|
||||
// Begin UBrainComponent overrides
|
||||
virtual void StartLogic() override;
|
||||
virtual void RestartLogic() override;
|
||||
virtual void StopLogic(const FString& Reason) override;
|
||||
virtual void PauseLogic(const FString& Reason) override;
|
||||
virtual EAILogicResuming::Type ResumeLogic(const FString& Reason) override;
|
||||
|
||||
/** indicates instance has been initialized to work with specific BT asset */
|
||||
bool TreeHasBeenStarted() const;
|
||||
|
||||
public:
|
||||
/** DO NOT USE. This constructor is for internal usage only for hot-reload purposes. */
|
||||
UBehaviorTreeComponent(FVTableHelper& Helper);
|
||||
|
||||
virtual bool IsRunning() const override;
|
||||
virtual bool IsPaused() const override;
|
||||
virtual void Cleanup() override;
|
||||
virtual void HandleMessage(const FAIMessage& Message) override;
|
||||
// End UBrainComponent overrides
|
||||
|
||||
// Begin UActorComponent overrides
|
||||
virtual void UninitializeComponent() override;
|
||||
// End UActorComponent overrides
|
||||
|
||||
/** starts execution from root */
|
||||
void StartTree(UBehaviorTree& Asset, EBTExecutionMode::Type ExecuteMode = EBTExecutionMode::Looped);
|
||||
|
||||
/** stops execution */
|
||||
void StopTree(EBTStopMode::Type StopMode = EBTStopMode::Safe);
|
||||
|
||||
/** restarts execution from root */
|
||||
void RestartTree();
|
||||
|
||||
/** request execution change */
|
||||
void RequestExecution(UBTCompositeNode* RequestedOn, int32 InstanceIdx,
|
||||
const UBTNode* RequestedBy, int32 RequestedByChildIndex,
|
||||
EBTNodeResult::Type ContinueWithResult, bool bStoreForDebugger = true);
|
||||
|
||||
/** request execution change: helpers for decorator nodes */
|
||||
void RequestExecution(const UBTDecorator* RequestedBy);
|
||||
|
||||
/** request execution change: helpers for task nodes */
|
||||
void RequestExecution(EBTNodeResult::Type ContinueWithResult);
|
||||
|
||||
/** request unregistration of aux nodes in the specified branch */
|
||||
void RequestUnregisterAuxNodesInBranch(const UBTCompositeNode* Node);
|
||||
|
||||
/** finish latent execution or abort */
|
||||
void OnTaskFinished(const UBTTaskNode* TaskNode, EBTNodeResult::Type TaskResult);
|
||||
|
||||
/** setup message observer for given task */
|
||||
void RegisterMessageObserver(const UBTTaskNode* TaskNode, FName MessageType);
|
||||
void RegisterMessageObserver(const UBTTaskNode* TaskNode, FName MessageType, FAIRequestID MessageID);
|
||||
|
||||
/** remove message observers registered with task */
|
||||
void UnregisterMessageObserversFrom(const UBTTaskNode* TaskNode);
|
||||
void UnregisterMessageObserversFrom(const FBTNodeIndex& TaskIdx);
|
||||
|
||||
/** add active parallel task */
|
||||
void RegisterParallelTask(const UBTTaskNode* TaskNode);
|
||||
|
||||
/** remove parallel task */
|
||||
void UnregisterParallelTask(const UBTTaskNode* TaskNode, uint16 InstanceIdx);
|
||||
|
||||
/** unregister all aux nodes less important than given index */
|
||||
void UnregisterAuxNodesUpTo(const FBTNodeIndex& Index);
|
||||
|
||||
/** unregister all aux nodes between given execution index range: FromIndex < AuxIndex < ToIndex */
|
||||
void UnregisterAuxNodesInRange(const FBTNodeIndex& FromIndex, const FBTNodeIndex& ToIndex);
|
||||
|
||||
/** unregister all aux nodes in branch of tree */
|
||||
UE_DEPRECATED(4.26, "This function is deprecated. Please use RequestUnregisterAuxNodesInBranch instead.")
|
||||
void UnregisterAuxNodesInBranch(const UBTCompositeNode* Node, bool bApplyImmediately = true);
|
||||
|
||||
/** BEGIN UActorComponent overrides */
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
/** END UActorComponent overrides */
|
||||
|
||||
/** Schedule when will be the next tick, 0.0f means next frame, FLT_MAX means never */
|
||||
void ScheduleNextTick(float NextDeltaTime);
|
||||
|
||||
/** process execution flow */
|
||||
void ProcessExecutionRequest();
|
||||
|
||||
/** schedule execution flow update in next tick */
|
||||
void ScheduleExecutionUpdate();
|
||||
|
||||
/** tries to find behavior tree instance in context */
|
||||
int32 FindInstanceContainingNode(const UBTNode* Node) const;
|
||||
|
||||
/** tries to find template node for given instanced node */
|
||||
UBTNode* FindTemplateNode(const UBTNode* Node) const;
|
||||
|
||||
/** @return current tree */
|
||||
UBehaviorTree* GetCurrentTree() const;
|
||||
|
||||
/** @return tree from top of instance stack */
|
||||
UBehaviorTree* GetRootTree() const;
|
||||
|
||||
/** @return active node */
|
||||
const UBTNode* GetActiveNode() const;
|
||||
|
||||
/** get index of active instance on stack */
|
||||
uint16 GetActiveInstanceIdx() const;
|
||||
|
||||
/** @return node memory */
|
||||
uint8* GetNodeMemory(UBTNode* Node, int32 InstanceIdx) const;
|
||||
|
||||
/** @return true if ExecutionRequest is switching to higher priority node */
|
||||
bool IsRestartPending() const;
|
||||
|
||||
/** @return true if waiting for abort to finish */
|
||||
bool IsAbortPending() const;
|
||||
|
||||
/** @return true if active node is one of child nodes of given one */
|
||||
bool IsExecutingBranch(const UBTNode* Node, int32 ChildIndex = -1) const;
|
||||
|
||||
/** @return true if aux node is currently active */
|
||||
bool IsAuxNodeActive(const UBTAuxiliaryNode* AuxNode) const;
|
||||
bool IsAuxNodeActive(const UBTAuxiliaryNode* AuxNodeTemplate, int32 InstanceIdx) const;
|
||||
|
||||
/** Returns true if InstanceStack contains any BT runtime instances */
|
||||
bool IsInstanceStackEmpty() const { return (InstanceStack.Num() == 0); }
|
||||
|
||||
/** @return status of speficied task */
|
||||
EBTTaskStatus::Type GetTaskStatus(const UBTTaskNode* TaskNode) const;
|
||||
|
||||
virtual FString GetDebugInfoString() const override;
|
||||
virtual FString DescribeActiveTasks() const;
|
||||
virtual FString DescribeActiveTrees() const;
|
||||
|
||||
/** @return the cooldown tag end time, 0.0f if CooldownTag is not found */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Logic")
|
||||
float GetTagCooldownEndTime(FGameplayTag CooldownTag) const;
|
||||
|
||||
/** add to the cooldown tag's duration */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Logic")
|
||||
void AddCooldownTagDuration(FGameplayTag CooldownTag, float CooldownDuration, bool bAddToExistingDuration);
|
||||
|
||||
/** assign subtree to RunBehaviorDynamic task specified by tag */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Logic")
|
||||
virtual void SetDynamicSubtree(FGameplayTag InjectTag, UBehaviorTree* BehaviorAsset);
|
||||
|
||||
// Code for timing BT Search for FramePro
|
||||
#if !UE_BUILD_SHIPPING
|
||||
static void EndFrame();
|
||||
#endif
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
virtual void DescribeSelfToVisLog(struct FVisualLogEntry* Snapshot) const override;
|
||||
#endif
|
||||
|
||||
#if CSV_PROFILER
|
||||
/** Set a custom CSV tick stat name, must point to a static string */
|
||||
void SetCSVTickStatName(const char* InCSVTickStatName) { CSVTickStatName = InCSVTickStatName; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** stack of behavior tree instances */
|
||||
TArray<FBehaviorTreeInstance> InstanceStack;
|
||||
|
||||
/** list of known subtree instances */
|
||||
TArray<FBehaviorTreeInstanceId> KnownInstances;
|
||||
|
||||
/** instanced nodes */
|
||||
UPROPERTY(transient)
|
||||
TArray<UBTNode*> NodeInstances;
|
||||
|
||||
/** search data being currently used */
|
||||
FBehaviorTreeSearchData SearchData;
|
||||
|
||||
/** execution request, search will be performed when current task finish execution/aborting */
|
||||
FBTNodeExecutionInfo ExecutionRequest;
|
||||
|
||||
/** result of ExecutionRequest, will be applied when current task finish aborting */
|
||||
FBTPendingExecutionInfo PendingExecution;
|
||||
|
||||
/** list of all pending aux nodes unregistration requests */
|
||||
FBTPendingAuxNodesUnregisterInfo PendingUnregisterAuxNodesRequests;
|
||||
|
||||
/** stored data for starting new tree, waits until previously running finishes aborting */
|
||||
FBTTreeStartInfo TreeStartInfo;
|
||||
|
||||
/** message observers mapped by instance & execution index */
|
||||
TMultiMap<FBTNodeIndex,FAIMessageObserverHandle> TaskMessageObservers;
|
||||
|
||||
/** behavior cooldowns mapped by tag to last time it was set */
|
||||
TMap<FGameplayTag, float> CooldownTagsMap;
|
||||
|
||||
#if USE_BEHAVIORTREE_DEBUGGER
|
||||
/** search flow for debugger */
|
||||
mutable TArray<TArray<FBehaviorTreeDebuggerInstance::FNodeFlowData> > CurrentSearchFlow;
|
||||
mutable TArray<TArray<FBehaviorTreeDebuggerInstance::FNodeFlowData> > CurrentRestarts;
|
||||
mutable TMap<FName, FString> SearchStartBlackboard;
|
||||
mutable TArray<FBehaviorTreeDebuggerInstance> RemovedInstances;
|
||||
|
||||
/** debugger's recorded data */
|
||||
mutable TArray<FBehaviorTreeExecutionStep> DebuggerSteps;
|
||||
|
||||
/** set when at least one debugger window is opened */
|
||||
static int32 ActiveDebuggerCounter;
|
||||
#endif
|
||||
|
||||
// Code for timing BT Search for FramePro
|
||||
#if !UE_BUILD_SHIPPING
|
||||
static bool bAddedEndFrameCallback;
|
||||
static double FrameSearchTime;
|
||||
static int32 NumSearchTimeCalls;
|
||||
#endif
|
||||
|
||||
/** index of last active instance on stack */
|
||||
uint16 ActiveInstanceIdx;
|
||||
|
||||
/** if set, StopTree calls will be deferred */
|
||||
uint8 StopTreeLock;
|
||||
|
||||
/** if set, StopTree will be called at the end of tick */
|
||||
uint8 bDeferredStopTree : 1;
|
||||
|
||||
/** loops tree execution */
|
||||
uint8 bLoopExecution : 1;
|
||||
|
||||
/** set when execution is waiting for tasks to abort (current or parallel's main) */
|
||||
uint8 bWaitingForAbortingTasks : 1;
|
||||
|
||||
/** set when execution update is scheduled for next tick */
|
||||
uint8 bRequestedFlowUpdate : 1;
|
||||
|
||||
/** set when tree stop was called */
|
||||
uint8 bRequestedStop : 1;
|
||||
|
||||
/** if set, tree execution is allowed */
|
||||
uint8 bIsRunning : 1;
|
||||
|
||||
/** if set, execution requests will be postponed */
|
||||
uint8 bIsPaused : 1;
|
||||
|
||||
/** push behavior tree instance on execution stack
|
||||
* @NOTE: should never be called out-side of BT execution, meaning only BT tasks can push another BT instance! */
|
||||
bool PushInstance(UBehaviorTree& TreeAsset);
|
||||
|
||||
/** add unique Id of newly created subtree to KnownInstances list and return its index */
|
||||
uint8 UpdateInstanceId(UBehaviorTree* TreeAsset, const UBTNode* OriginNode, int32 OriginInstanceIdx);
|
||||
|
||||
/** remove instanced nodes, known subtree instances and safely clears their persistent memory */
|
||||
void RemoveAllInstances();
|
||||
|
||||
/** copy memory block from running instances to persistent memory */
|
||||
void CopyInstanceMemoryToPersistent();
|
||||
|
||||
/** copy memory block from persistent memory to running instances (rollback) */
|
||||
void CopyInstanceMemoryFromPersistent();
|
||||
|
||||
/** find next task to execute */
|
||||
UBTTaskNode* FindNextTask(UBTCompositeNode* ParentNode, uint16 ParentInstanceIdx, EBTNodeResult::Type LastResult);
|
||||
|
||||
/** called when tree runs out of nodes to execute */
|
||||
void OnTreeFinished();
|
||||
|
||||
/** apply pending node updates from SearchData */
|
||||
void ApplySearchData(UBTNode* NewActiveNode);
|
||||
|
||||
/** apply pending node updates required for discarded search */
|
||||
void ApplyDiscardedSearch();
|
||||
|
||||
/** apply updates from specific list */
|
||||
void ApplySearchUpdates(const TArray<FBehaviorTreeSearchUpdate>& UpdateList, int32 NewNodeExecutionIndex, bool bPostUpdate = false);
|
||||
|
||||
/** abort currently executed task */
|
||||
void AbortCurrentTask();
|
||||
|
||||
/** execute new task */
|
||||
void ExecuteTask(UBTTaskNode* TaskNode);
|
||||
|
||||
/** deactivate all nodes up to requested one */
|
||||
bool DeactivateUpTo(UBTCompositeNode* Node, uint16 NodeInstanceIdx, EBTNodeResult::Type& NodeResult, int32& OutLastDeactivatedChildIndex);
|
||||
|
||||
/** update state of aborting tasks */
|
||||
void UpdateAbortingTasks();
|
||||
|
||||
/** apply pending execution from last task search */
|
||||
void ProcessPendingExecution();
|
||||
|
||||
/** apply pending tree initialization */
|
||||
void ProcessPendingInitialize();
|
||||
|
||||
/**
|
||||
* apply pending unregister aux nodes requests
|
||||
* @return true if some request were processed, false otherwise
|
||||
*/
|
||||
bool ProcessPendingUnregister();
|
||||
|
||||
/** restore state of tree to state before search */
|
||||
void RollbackSearchChanges();
|
||||
|
||||
/** make a snapshot for debugger */
|
||||
void StoreDebuggerExecutionStep(EBTExecutionSnap::Type SnapType);
|
||||
|
||||
/** make a snapshot for debugger from given subtree instance */
|
||||
void StoreDebuggerInstance(FBehaviorTreeDebuggerInstance& InstanceInfo, uint16 InstanceIdx, EBTExecutionSnap::Type SnapType) const;
|
||||
void StoreDebuggerRemovedInstance(uint16 InstanceIdx) const;
|
||||
|
||||
/** store search step for debugger */
|
||||
void StoreDebuggerSearchStep(const UBTNode* Node, uint16 InstanceIdx, EBTNodeResult::Type NodeResult) const;
|
||||
void StoreDebuggerSearchStep(const UBTNode* Node, uint16 InstanceIdx, bool bPassed) const;
|
||||
|
||||
/** store restarting node for debugger */
|
||||
void StoreDebuggerRestart(const UBTNode* Node, uint16 InstanceIdx, bool bAllowed);
|
||||
|
||||
/** describe blackboard's key values */
|
||||
void StoreDebuggerBlackboard(TMap<FName, FString>& BlackboardValueDesc) const;
|
||||
|
||||
/** gather nodes runtime descriptions */
|
||||
void StoreDebuggerRuntimeValues(TArray<FString>& RuntimeDescriptions, UBTNode* RootNode, uint16 InstanceIdx) const;
|
||||
|
||||
/** update runtime description of given task node in latest debugger's snapshot */
|
||||
void UpdateDebuggerAfterExecution(const UBTTaskNode* TaskNode, uint16 InstanceIdx) const;
|
||||
|
||||
/** check if debugger is currently running and can gather data */
|
||||
static bool IsDebuggerActive();
|
||||
|
||||
/** Return NodeA's relative priority in regards to NodeB */
|
||||
EBTNodeRelativePriority CalculateRelativePriority(const UBTNode* NodeA, const UBTNode* NodeB) const;
|
||||
|
||||
friend UBTNode;
|
||||
friend UBTCompositeNode;
|
||||
friend UBTTaskNode;
|
||||
friend UBTTask_RunBehavior;
|
||||
friend UBTTask_RunBehaviorDynamic;
|
||||
friend FBehaviorTreeDebugger;
|
||||
friend FBehaviorTreeInstance;
|
||||
friend FScopedBehaviorTreeLock;
|
||||
|
||||
protected:
|
||||
/** data asset defining the tree */
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = AI)
|
||||
UBehaviorTree* DefaultBehaviorTreeAsset;
|
||||
|
||||
/** Used to tell tickmanager that we want interval ticking */
|
||||
bool bTickedOnce = false;
|
||||
/** Predicted next DeltaTime*/
|
||||
float NextTickDeltaTime = 0.0f;
|
||||
/** Accumulated DeltaTime if ticked more than predicted next delta time */
|
||||
float AccumulatedTickDeltaTime = 0.0f;
|
||||
/** GameTime of the last DeltaTime request, used for debugging to output warnings about ticking */
|
||||
float LastRequestedDeltaTimeGameTime = 0;
|
||||
|
||||
#if CSV_PROFILER
|
||||
/** CSV tick stat name. Can be changed but must point to a static string */
|
||||
const char* CSVTickStatName = "BehaviorTreeTick";
|
||||
#endif
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE UBehaviorTree* UBehaviorTreeComponent::GetCurrentTree() const
|
||||
{
|
||||
return InstanceStack.Num() ? KnownInstances[InstanceStack[ActiveInstanceIdx].InstanceIdIndex].TreeAsset : NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE UBehaviorTree* UBehaviorTreeComponent::GetRootTree() const
|
||||
{
|
||||
return InstanceStack.Num() ? KnownInstances[InstanceStack[0].InstanceIdIndex].TreeAsset : NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE const UBTNode* UBehaviorTreeComponent::GetActiveNode() const
|
||||
{
|
||||
return InstanceStack.Num() ? InstanceStack[ActiveInstanceIdx].ActiveNode : NULL;
|
||||
}
|
||||
|
||||
FORCEINLINE uint16 UBehaviorTreeComponent::GetActiveInstanceIdx() const
|
||||
{
|
||||
return ActiveInstanceIdx;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBehaviorTreeComponent::IsRestartPending() const
|
||||
{
|
||||
return ExecutionRequest.ExecuteNode && !ExecutionRequest.bTryNextChild;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBehaviorTreeComponent::IsAbortPending() const
|
||||
{
|
||||
return bWaitingForAbortingTasks || PendingExecution.IsSet();
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "BehaviorTreeManager.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
class UBehaviorTreeComponent;
|
||||
class UBTCompositeNode;
|
||||
class UBTDecorator;
|
||||
|
||||
USTRUCT()
|
||||
struct FBehaviorTreeTemplateInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
/** behavior tree asset */
|
||||
UPROPERTY()
|
||||
UBehaviorTree* Asset;
|
||||
|
||||
/** initialized template */
|
||||
UPROPERTY(transient)
|
||||
UBTCompositeNode* Template;
|
||||
|
||||
/** size required for instance memory */
|
||||
uint16 InstanceMemorySize;
|
||||
};
|
||||
|
||||
UCLASS(config=Engine, Transient)
|
||||
class AIMODULE_API UBehaviorTreeManager : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** limit for recording execution steps for debugger */
|
||||
UPROPERTY(config)
|
||||
int32 MaxDebuggerSteps;
|
||||
|
||||
/** get behavior tree template for given blueprint */
|
||||
bool LoadTree(UBehaviorTree& Asset, UBTCompositeNode*& Root, uint16& InstanceMemorySize);
|
||||
|
||||
/** get aligned memory size */
|
||||
static int32 GetAlignedDataSize(int32 Size);
|
||||
|
||||
/** helper function for sorting and aligning node memory */
|
||||
static void InitializeMemoryHelper(const TArray<UBTDecorator*>& Nodes, TArray<uint16>& MemoryOffsets, int32& MemorySize, bool bForceInstancing = false);
|
||||
|
||||
/** cleanup hooks for map loading */
|
||||
virtual void FinishDestroy() override;
|
||||
|
||||
void DumpUsageStats() const;
|
||||
|
||||
/** register new behavior tree component for tracking */
|
||||
void AddActiveComponent(UBehaviorTreeComponent& Component);
|
||||
|
||||
/** unregister behavior tree component from tracking */
|
||||
void RemoveActiveComponent(UBehaviorTreeComponent& Component);
|
||||
|
||||
static UBehaviorTreeManager* GetCurrent(UWorld* World);
|
||||
static UBehaviorTreeManager* GetCurrent(UObject* WorldContextObject);
|
||||
|
||||
protected:
|
||||
|
||||
/** initialized tree templates */
|
||||
UPROPERTY()
|
||||
TArray<FBehaviorTreeTemplateInfo> LoadedTemplates;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UBehaviorTreeComponent*> ActiveComponents;
|
||||
};
|
||||
@@ -1,666 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Stats/Stats.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "UObject/Class.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "BehaviorTreeTypes.generated.h"
|
||||
|
||||
class FBlackboardDecoratorDetails;
|
||||
class UBehaviorTree;
|
||||
class UBehaviorTreeComponent;
|
||||
class UBlackboardComponent;
|
||||
class UBlackboardData;
|
||||
class UBlackboardKeyType;
|
||||
class UBTAuxiliaryNode;
|
||||
class UBTCompositeNode;
|
||||
class UBTNode;
|
||||
class UBTTaskNode;
|
||||
struct FBehaviorTreeSearchData;
|
||||
|
||||
// Visual logging helper
|
||||
#define BT_VLOG(Context, Verbosity, Format, ...) UE_VLOG(Context->OwnerComp.IsValid() ? Context->OwnerComp->GetOwner() : NULL, LogBehaviorTree, Verbosity, Format, ##__VA_ARGS__)
|
||||
#define BT_SEARCHLOG(SearchData, Verbosity, Format, ...) UE_VLOG(SearchData.OwnerComp.GetOwner(), LogBehaviorTree, Verbosity, Format, ##__VA_ARGS__)
|
||||
|
||||
// Behavior tree debugger in editor
|
||||
#define USE_BEHAVIORTREE_DEBUGGER (1 && WITH_EDITORONLY_DATA)
|
||||
|
||||
DECLARE_STATS_GROUP(TEXT("Behavior Tree"), STATGROUP_AIBehaviorTree, STATCAT_Advanced);
|
||||
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Tick"),STAT_AI_BehaviorTree_Tick,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Load Time"),STAT_AI_BehaviorTree_LoadTime,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Search Time"),STAT_AI_BehaviorTree_SearchTime,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Execution Time"),STAT_AI_BehaviorTree_ExecutionTime,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Auxiliary Update Time"),STAT_AI_BehaviorTree_AuxUpdateTime,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Cleanup Time"), STAT_AI_BehaviorTree_Cleanup, STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_CYCLE_STAT_EXTERN(TEXT("BT Stop Tree Time"), STAT_AI_BehaviorTree_StopTree, STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_DWORD_ACCUMULATOR_STAT_EXTERN(TEXT("Num Templates"),STAT_AI_BehaviorTree_NumTemplates,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_DWORD_ACCUMULATOR_STAT_EXTERN(TEXT("Num Instances"),STAT_AI_BehaviorTree_NumInstances,STATGROUP_AIBehaviorTree, );
|
||||
DECLARE_MEMORY_STAT_EXTERN(TEXT("Instance memory"),STAT_AI_BehaviorTree_InstanceMemory,STATGROUP_AIBehaviorTree, AIMODULE_API);
|
||||
|
||||
namespace FBlackboard
|
||||
{
|
||||
const FName KeySelf = TEXT("SelfActor");
|
||||
|
||||
typedef uint8 FKey;
|
||||
|
||||
const FKey InvalidKey = FKey(-1);
|
||||
}
|
||||
|
||||
enum class EBlackboardNotificationResult : uint8
|
||||
{
|
||||
RemoveObserver,
|
||||
ContinueObserving
|
||||
};
|
||||
|
||||
// delegate defines
|
||||
DECLARE_DELEGATE_TwoParams(FOnBlackboardChange, const UBlackboardComponent&, FBlackboard::FKey /*key ID*/);
|
||||
DECLARE_DELEGATE_RetVal_TwoParams(EBlackboardNotificationResult, FOnBlackboardChangeNotification, const UBlackboardComponent&, FBlackboard::FKey /*key ID*/);
|
||||
|
||||
namespace BTSpecialChild
|
||||
{
|
||||
const int32 NotInitialized = -1; // special value for child indices: needs to be initialized
|
||||
const int32 ReturnToParent = -2; // special value for child indices: return to parent node
|
||||
|
||||
const uint8 OwnedByComposite = MAX_uint8; // special value for aux node's child index: owned by composite node instead of a task
|
||||
}
|
||||
|
||||
UENUM(BlueprintType)
|
||||
namespace EBTNodeResult
|
||||
{
|
||||
// keep in sync with DescribeNodeResult()
|
||||
enum Type
|
||||
{
|
||||
Succeeded, // finished as success
|
||||
Failed, // finished as failure
|
||||
Aborted, // finished aborting = failure
|
||||
InProgress, // not finished yet
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTExecutionMode
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
SingleRun,
|
||||
Looped,
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTStopMode
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Safe,
|
||||
Forced,
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTMemoryInit
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Initialize, // first time initialization
|
||||
RestoreSubtree, // loading saved data on reentering subtree
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTMemoryClear
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Destroy, // final clear
|
||||
StoreSubtree, // saving data on leaving subtree
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EBTFlowAbortMode
|
||||
{
|
||||
// keep in sync with DescribeFlowAbortMode()
|
||||
|
||||
enum Type
|
||||
{
|
||||
None UMETA(DisplayName="Nothing"),
|
||||
LowerPriority UMETA(DisplayName="Lower Priority"),
|
||||
Self UMETA(DisplayName="Self"),
|
||||
Both UMETA(DisplayName="Both"),
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTActiveNode
|
||||
{
|
||||
// keep in sync with DescribeActiveNode()
|
||||
enum Type
|
||||
{
|
||||
Composite,
|
||||
ActiveTask,
|
||||
AbortingTask,
|
||||
InactiveTask,
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTTaskStatus
|
||||
{
|
||||
// keep in sync with DescribeTaskStatus()
|
||||
enum Type
|
||||
{
|
||||
Active,
|
||||
Aborting,
|
||||
Inactive,
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTNodeUpdateMode
|
||||
{
|
||||
// keep in sync with DescribeNodeUpdateMode()
|
||||
enum Type
|
||||
{
|
||||
Unknown,
|
||||
Add, // add node
|
||||
Remove, // remove node
|
||||
};
|
||||
}
|
||||
|
||||
/** wrapper struct for holding a parallel task node and its status */
|
||||
struct FBehaviorTreeParallelTask
|
||||
{
|
||||
/** worker object */
|
||||
const UBTTaskNode* TaskNode;
|
||||
|
||||
/** additional mode data used for context switching */
|
||||
EBTTaskStatus::Type Status;
|
||||
|
||||
FBehaviorTreeParallelTask() : TaskNode(NULL) {}
|
||||
FBehaviorTreeParallelTask(const UBTTaskNode* InTaskNode, EBTTaskStatus::Type InStatus) : TaskNode(InTaskNode), Status(InStatus) {}
|
||||
|
||||
bool operator==(const FBehaviorTreeParallelTask& Other) const { return TaskNode == Other.TaskNode; }
|
||||
bool operator==(const UBTTaskNode* OtherTask) const { return TaskNode == OtherTask; }
|
||||
};
|
||||
|
||||
namespace EBTExecutionSnap
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Regular,
|
||||
OutOfNodes,
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBTDescriptionVerbosity
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Basic,
|
||||
Detailed,
|
||||
};
|
||||
}
|
||||
|
||||
enum class EBTNodeRelativePriority : uint8
|
||||
{
|
||||
Lower,
|
||||
Same,
|
||||
Higher
|
||||
};
|
||||
|
||||
/** debugger data about subtree instance */
|
||||
struct FBehaviorTreeDebuggerInstance
|
||||
{
|
||||
struct FNodeFlowData
|
||||
{
|
||||
uint16 ExecutionIndex;
|
||||
uint16 bPassed : 1;
|
||||
uint16 bTrigger : 1;
|
||||
uint16 bDiscardedTrigger : 1;
|
||||
|
||||
FNodeFlowData() : ExecutionIndex(INDEX_NONE), bPassed(0), bTrigger(0), bDiscardedTrigger(0) {}
|
||||
};
|
||||
|
||||
FBehaviorTreeDebuggerInstance() : TreeAsset(NULL), RootNode(NULL) {}
|
||||
|
||||
/** behavior tree asset */
|
||||
UBehaviorTree* TreeAsset;
|
||||
|
||||
/** root node in template */
|
||||
UBTCompositeNode* RootNode;
|
||||
|
||||
/** execution indices of active nodes */
|
||||
TArray<uint16> ActivePath;
|
||||
|
||||
/** execution indices of active nodes */
|
||||
TArray<uint16> AdditionalActiveNodes;
|
||||
|
||||
/** search flow from previous state */
|
||||
TArray<FNodeFlowData> PathFromPrevious;
|
||||
|
||||
/** runtime descriptions for each execution index */
|
||||
TArray<FString> RuntimeDesc;
|
||||
|
||||
FORCEINLINE bool IsValid() const { return ActivePath.Num() != 0; }
|
||||
};
|
||||
|
||||
/** debugger data about current execution step */
|
||||
struct FBehaviorTreeExecutionStep
|
||||
{
|
||||
FBehaviorTreeExecutionStep() : TimeStamp(0.f), ExecutionStepId(InvalidExecutionId) {}
|
||||
|
||||
/** subtree instance stack */
|
||||
TArray<FBehaviorTreeDebuggerInstance> InstanceStack;
|
||||
|
||||
/** blackboard snapshot: value descriptions */
|
||||
TMap<FName, FString> BlackboardValues;
|
||||
|
||||
/** Game world's time stamp of this step */
|
||||
float TimeStamp;
|
||||
|
||||
static constexpr int32 InvalidExecutionId = -1;
|
||||
|
||||
/** Id of execution step */
|
||||
int32 ExecutionStepId;
|
||||
};
|
||||
|
||||
/** identifier of subtree instance */
|
||||
struct FBehaviorTreeInstanceId
|
||||
{
|
||||
/** behavior tree asset */
|
||||
UBehaviorTree* TreeAsset;
|
||||
|
||||
/** root node in template for cleanup purposes */
|
||||
UBTCompositeNode* RootNode;
|
||||
|
||||
/** execution index path from root */
|
||||
TArray<uint16> Path;
|
||||
|
||||
/** persistent instance memory */
|
||||
TArray<uint8> InstanceMemory;
|
||||
|
||||
/** index of first node instance (BehaviorTreeComponent.NodeInstances) */
|
||||
int32 FirstNodeInstance;
|
||||
|
||||
FBehaviorTreeInstanceId() : TreeAsset(0), RootNode(0), FirstNodeInstance(-1) {}
|
||||
|
||||
bool operator==(const FBehaviorTreeInstanceId& Other) const
|
||||
{
|
||||
return (TreeAsset == Other.TreeAsset) && (Path == Other.Path);
|
||||
}
|
||||
};
|
||||
|
||||
struct FBehaviorTreeSearchData;
|
||||
DECLARE_DELEGATE_TwoParams(FBTInstanceDeactivation, UBehaviorTreeComponent&, EBTNodeResult::Type);
|
||||
|
||||
/** data required for instance of single subtree */
|
||||
struct FBehaviorTreeInstance
|
||||
{
|
||||
/** root node in template */
|
||||
UBTCompositeNode* RootNode;
|
||||
|
||||
/** active node in template */
|
||||
UBTNode* ActiveNode;
|
||||
|
||||
/** active auxiliary nodes */
|
||||
TArray<UBTAuxiliaryNode*> ActiveAuxNodes;
|
||||
|
||||
/** active parallel tasks */
|
||||
TArray<FBehaviorTreeParallelTask> ParallelTasks;
|
||||
|
||||
/** memory: instance */
|
||||
TArray<uint8> InstanceMemory;
|
||||
|
||||
/** index of identifier (BehaviorTreeComponent.KnownInstances) */
|
||||
uint8 InstanceIdIndex;
|
||||
|
||||
/** active node type */
|
||||
TEnumAsByte<EBTActiveNode::Type> ActiveNodeType;
|
||||
|
||||
/** delegate sending a notify when tree instance is removed from active stack */
|
||||
FBTInstanceDeactivation DeactivationNotify;
|
||||
|
||||
AIMODULE_API FBehaviorTreeInstance();
|
||||
AIMODULE_API FBehaviorTreeInstance(const FBehaviorTreeInstance& Other);
|
||||
AIMODULE_API FBehaviorTreeInstance(int32 MemorySize);
|
||||
AIMODULE_API ~FBehaviorTreeInstance();
|
||||
|
||||
#if STATS
|
||||
void IncMemoryStats() const;
|
||||
void DecMemoryStats() const;
|
||||
uint32 GetAllocatedSize() const;
|
||||
#else
|
||||
FORCEINLINE uint32 GetAllocatedSize() const { return 0; }
|
||||
FORCEINLINE void IncMemoryStats() const {}
|
||||
FORCEINLINE void DecMemoryStats() const {}
|
||||
#endif // STATS
|
||||
|
||||
/** initialize memory and create node instances */
|
||||
void Initialize(UBehaviorTreeComponent& OwnerComp, UBTCompositeNode& Node, int32& InstancedIndex, EBTMemoryInit::Type InitType);
|
||||
|
||||
/** cleanup node instances */
|
||||
void Cleanup(UBehaviorTreeComponent& OwnerComp, EBTMemoryClear::Type CleanupType);
|
||||
|
||||
/** check if instance has active node with given execution index */
|
||||
bool HasActiveNode(uint16 TestExecutionIndex) const;
|
||||
|
||||
/** deactivate all active aux nodes and remove their requests from SearchData */
|
||||
void DeactivateNodes(FBehaviorTreeSearchData& SearchData, uint16 InstanceIndex);
|
||||
|
||||
/** get list of all active auxiliary nodes */
|
||||
TArrayView<UBTAuxiliaryNode* const> GetActiveAuxNodes() const { return ActiveAuxNodes; }
|
||||
|
||||
/** add specified node to the active nodes list */
|
||||
void AddToActiveAuxNodes(UBTAuxiliaryNode* AuxNode);
|
||||
|
||||
/** remove specified node from the active nodes list */
|
||||
void RemoveFromActiveAuxNodes(UBTAuxiliaryNode* AuxNode);
|
||||
|
||||
/** remove all auxiliary nodes from active nodes list */
|
||||
void ResetActiveAuxNodes();
|
||||
|
||||
/** iterate on auxiliary nodes and call ExecFunc on each of them. Nodes can not be added or removed during the iteration */
|
||||
void ExecuteOnEachAuxNode(TFunctionRef<void(const UBTAuxiliaryNode&)> ExecFunc);
|
||||
|
||||
/** get list of all active parallel tasks */
|
||||
TArrayView<const FBehaviorTreeParallelTask> GetParallelTasks() const { return ParallelTasks; }
|
||||
|
||||
/** add new parallel task */
|
||||
void AddToParallelTasks(FBehaviorTreeParallelTask&& ParallelTask);
|
||||
|
||||
/** remove parallel task at given index */
|
||||
void RemoveParallelTaskAt(int32 TaskIndex);
|
||||
|
||||
/** mark parallel task at given index as pending abort */
|
||||
void MarkParallelTaskAsAbortingAt(int32 TaskIndex);
|
||||
|
||||
/** indicates if the provided index is a valid parallel task index */
|
||||
bool IsValidParallelTaskIndex(const int32 Index) const { return ParallelTasks.IsValidIndex(Index); }
|
||||
|
||||
/** iterate on parallel tasks and call ExecFunc on each of them. Supports removing the iterated task while processed */
|
||||
void ExecuteOnEachParallelTask(TFunctionRef<void(const FBehaviorTreeParallelTask&, const int32)> ExecFunc);
|
||||
|
||||
/** set instance memory */
|
||||
void SetInstanceMemory(const TArray<uint8>& Memory);
|
||||
|
||||
/** get instance memory */
|
||||
TArrayView<const uint8> GetInstanceMemory() const { return InstanceMemory; }
|
||||
|
||||
protected:
|
||||
|
||||
/** worker for updating all nodes */
|
||||
void CleanupNodes(UBehaviorTreeComponent& OwnerComp, UBTCompositeNode& Node, EBTMemoryClear::Type CleanupType);
|
||||
|
||||
private:
|
||||
#if DO_ENSURE
|
||||
/** debug flag to detect modifications to the array of nodes while iterating through it */
|
||||
bool bIteratingNodes = false;
|
||||
|
||||
/**
|
||||
* debug flag to detect forbidden modifications to the array of parallel tasks while iterating through it
|
||||
* the only allowed modification is to unregister the task on which the exec function is executed
|
||||
* @see ExecuteOnEachParallelTask
|
||||
*/
|
||||
int32 ParallelTaskIndex = INDEX_NONE;
|
||||
#endif // DO_ENSURE
|
||||
};
|
||||
|
||||
struct FBTNodeIndex
|
||||
{
|
||||
/** index of instance of stack */
|
||||
uint16 InstanceIndex;
|
||||
|
||||
/** execution index within instance */
|
||||
uint16 ExecutionIndex;
|
||||
|
||||
FBTNodeIndex() : InstanceIndex(MAX_uint16), ExecutionIndex(MAX_uint16) {}
|
||||
FBTNodeIndex(uint16 InInstanceIndex, uint16 InExecutionIndex) : InstanceIndex(InInstanceIndex), ExecutionIndex(InExecutionIndex) {}
|
||||
|
||||
bool TakesPriorityOver(const FBTNodeIndex& Other) const;
|
||||
bool IsSet() const { return InstanceIndex < MAX_uint16; }
|
||||
|
||||
FORCEINLINE bool operator==(const FBTNodeIndex& Other) const { return Other.ExecutionIndex == ExecutionIndex && Other.InstanceIndex == InstanceIndex; }
|
||||
FORCEINLINE bool operator!=(const FBTNodeIndex& Other) const { return !operator==(Other); }
|
||||
FORCEINLINE friend uint32 GetTypeHash(const FBTNodeIndex& Other) { return Other.ExecutionIndex ^ Other.InstanceIndex; }
|
||||
|
||||
FORCEINLINE FString Describe() const { return FString::Printf(TEXT("[%d:%d]"), InstanceIndex, ExecutionIndex); }
|
||||
};
|
||||
|
||||
struct FBTNodeIndexRange
|
||||
{
|
||||
/** first node index */
|
||||
FBTNodeIndex FromIndex;
|
||||
|
||||
/** last node index */
|
||||
FBTNodeIndex ToIndex;
|
||||
|
||||
FBTNodeIndexRange(const FBTNodeIndex& From, const FBTNodeIndex& To) : FromIndex(From), ToIndex(To) {}
|
||||
|
||||
bool IsSet() const { return FromIndex.IsSet() && ToIndex.IsSet(); }
|
||||
|
||||
bool operator==(const FBTNodeIndexRange& Other) const { return Other.FromIndex == FromIndex && Other.ToIndex == ToIndex; }
|
||||
bool operator!=(const FBTNodeIndexRange& Other) const { return !operator==(Other); }
|
||||
|
||||
bool Contains(const FBTNodeIndex& Index) const
|
||||
{
|
||||
return Index.InstanceIndex == FromIndex.InstanceIndex && FromIndex.ExecutionIndex <= Index.ExecutionIndex && Index.ExecutionIndex <= ToIndex.ExecutionIndex;
|
||||
}
|
||||
|
||||
FString Describe() const { return FString::Printf(TEXT("[%s...%s]"), *FromIndex.Describe(), *ToIndex.Describe()); }
|
||||
};
|
||||
|
||||
/** node update data */
|
||||
struct FBehaviorTreeSearchUpdate
|
||||
{
|
||||
UBTAuxiliaryNode* AuxNode;
|
||||
UBTTaskNode* TaskNode;
|
||||
|
||||
uint16 InstanceIndex;
|
||||
|
||||
TEnumAsByte<EBTNodeUpdateMode::Type> Mode;
|
||||
|
||||
/** if set, this entry will be applied AFTER other are processed */
|
||||
uint8 bPostUpdate : 1;
|
||||
|
||||
FBehaviorTreeSearchUpdate() : AuxNode(0), TaskNode(0), InstanceIndex(0), Mode(EBTNodeUpdateMode::Unknown), bPostUpdate(false) {}
|
||||
FBehaviorTreeSearchUpdate(const UBTAuxiliaryNode* InAuxNode, uint16 InInstanceIndex, EBTNodeUpdateMode::Type InMode) :
|
||||
AuxNode((UBTAuxiliaryNode*)InAuxNode), TaskNode(0), InstanceIndex(InInstanceIndex), Mode(InMode), bPostUpdate(false)
|
||||
{}
|
||||
FBehaviorTreeSearchUpdate(const UBTTaskNode* InTaskNode, uint16 InInstanceIndex, EBTNodeUpdateMode::Type InMode) :
|
||||
AuxNode(0), TaskNode((UBTTaskNode*)InTaskNode), InstanceIndex(InInstanceIndex), Mode(InMode), bPostUpdate(false)
|
||||
{}
|
||||
};
|
||||
|
||||
/** instance notify data */
|
||||
struct FBehaviorTreeSearchUpdateNotify
|
||||
{
|
||||
uint16 InstanceIndex;
|
||||
TEnumAsByte<EBTNodeResult::Type> NodeResult;
|
||||
|
||||
FBehaviorTreeSearchUpdateNotify() : InstanceIndex(0), NodeResult(EBTNodeResult::Succeeded) {}
|
||||
FBehaviorTreeSearchUpdateNotify(uint16 InInstanceIndex, EBTNodeResult::Type InNodeResult) : InstanceIndex(InInstanceIndex), NodeResult(InNodeResult) {}
|
||||
};
|
||||
|
||||
/** node search data */
|
||||
struct FBehaviorTreeSearchData
|
||||
{
|
||||
/** BT component */
|
||||
UBehaviorTreeComponent& OwnerComp;
|
||||
|
||||
/** requested updates of additional nodes (preconditions, services, parallels)
|
||||
* buffered during search to prevent instant add & remove pairs */
|
||||
TArray<FBehaviorTreeSearchUpdate> PendingUpdates;
|
||||
|
||||
/** notifies for tree instances */
|
||||
TArray<FBehaviorTreeSearchUpdateNotify> PendingNotifies;
|
||||
|
||||
/** node under which the search was performed */
|
||||
FBTNodeIndex SearchRootNode;
|
||||
|
||||
/** first node allowed in search */
|
||||
FBTNodeIndex SearchStart;
|
||||
|
||||
/** last node allowed in search */
|
||||
FBTNodeIndex SearchEnd;
|
||||
|
||||
/** search unique number */
|
||||
int32 SearchId;
|
||||
|
||||
/** active instance index to rollback to */
|
||||
int32 RollbackInstanceIdx;
|
||||
|
||||
/** start index of the deactivated branch */
|
||||
FBTNodeIndex DeactivatedBranchStart;
|
||||
|
||||
/** end index of the deactivated branch */
|
||||
FBTNodeIndex DeactivatedBranchEnd;
|
||||
|
||||
/** saved start index of the deactivated branch for rollback */
|
||||
FBTNodeIndex RollbackDeactivatedBranchStart;
|
||||
|
||||
/** saved end index of the deactivated branch for rollback */
|
||||
FBTNodeIndex RollbackDeactivatedBranchEnd;
|
||||
|
||||
/** if set, execution request from node in the deactivated branch will be skipped */
|
||||
uint32 bFilterOutRequestFromDeactivatedBranch : 1;
|
||||
|
||||
/** if set, current search will be restarted in next tick */
|
||||
uint32 bPostponeSearch : 1;
|
||||
|
||||
/** set when task search is in progress */
|
||||
uint32 bSearchInProgress : 1;
|
||||
|
||||
/** if set, active node state/memory won't be rolled back */
|
||||
uint32 bPreserveActiveNodeMemoryOnRollback : 1;
|
||||
|
||||
/** adds update info to PendingUpdates array, removing all previous updates for this node */
|
||||
void AddUniqueUpdate(const FBehaviorTreeSearchUpdate& UpdateInfo);
|
||||
|
||||
/** assign unique Id number */
|
||||
void AssignSearchId();
|
||||
|
||||
/** clear state of search */
|
||||
void Reset();
|
||||
|
||||
FBehaviorTreeSearchData(UBehaviorTreeComponent& InOwnerComp)
|
||||
: OwnerComp(InOwnerComp), RollbackInstanceIdx(INDEX_NONE)
|
||||
, bFilterOutRequestFromDeactivatedBranch(false)
|
||||
, bPostponeSearch(false)
|
||||
, bSearchInProgress(false)
|
||||
, bPreserveActiveNodeMemoryOnRollback(false)
|
||||
{}
|
||||
|
||||
FBehaviorTreeSearchData() = delete;
|
||||
|
||||
private:
|
||||
|
||||
static int32 NextSearchId;
|
||||
};
|
||||
|
||||
/** property block in blueprint defined nodes */
|
||||
struct FBehaviorTreePropertyMemory
|
||||
{
|
||||
uint16 Offset;
|
||||
uint16 BlockSize;
|
||||
|
||||
FBehaviorTreePropertyMemory() {}
|
||||
FBehaviorTreePropertyMemory(int32 Value) : Offset((uint32)Value >> 16), BlockSize((uint32)Value & 0xFFFF) {}
|
||||
|
||||
int32 Pack() const { return (int32)(((uint32)Offset << 16) | BlockSize); }
|
||||
};
|
||||
|
||||
/** helper struct for defining types of allowed blackboard entries
|
||||
* (e.g. only entries holding points and objects derived form actor class) */
|
||||
USTRUCT(BlueprintType)
|
||||
struct AIMODULE_API FBlackboardKeySelector
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FBlackboardKeySelector() : SelectedKeyID(FBlackboard::InvalidKey), bNoneIsAllowedValue(false)
|
||||
{}
|
||||
|
||||
/** array of allowed types with additional properties (e.g. uobject's base class)
|
||||
* EditAnywhere is required for FBlackboardSelectorDetails::CacheBlackboardData() */
|
||||
UPROPERTY(transient, EditAnywhere, BlueprintReadWrite, Category = Blackboard)
|
||||
TArray<UBlackboardKeyType*> AllowedTypes;
|
||||
|
||||
/** name of selected key */
|
||||
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = Blackboard)
|
||||
FName SelectedKeyName;
|
||||
|
||||
/** class of selected key */
|
||||
UPROPERTY(transient, EditInstanceOnly, BlueprintReadWrite, Category = Blackboard)
|
||||
TSubclassOf<UBlackboardKeyType> SelectedKeyType;
|
||||
|
||||
protected:
|
||||
/** ID of selected key */
|
||||
UPROPERTY(transient, EditInstanceOnly, BlueprintReadWrite, Category = Blackboard)
|
||||
uint8 SelectedKeyID;
|
||||
// SelectedKeyId type should be FBlackboard::FKey, but typedefs are not supported by UHT
|
||||
static_assert(sizeof(uint8) == sizeof(FBlackboard::FKey), "FBlackboardKeySelector::SelectedKeyId should be of FBlackboard::FKey-compatible type.");
|
||||
|
||||
// Requires BlueprintReadWrite so that blueprint creators (using MakeBlackboardKeySelector) can specify whether or not None is Allowed.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Blackboard, Meta = (Tooltip = ""))
|
||||
uint32 bNoneIsAllowedValue:1;
|
||||
|
||||
/** find initial selection. Called when None is not a valid option for this key selector */
|
||||
void InitSelection(const UBlackboardData& BlackboardAsset);
|
||||
|
||||
public:
|
||||
/** find ID and class of selected key */
|
||||
void ResolveSelectedKey(const UBlackboardData& BlackboardAsset);
|
||||
|
||||
void AllowNoneAsValue(bool bAllow) { bNoneIsAllowedValue = bAllow; }
|
||||
|
||||
FORCEINLINE FBlackboard::FKey GetSelectedKeyID() const { return SelectedKeyID; }
|
||||
|
||||
/** helper functions for setting basic filters */
|
||||
void AddObjectFilter(UObject* Owner, FName PropertyName, TSubclassOf<UObject> AllowedClass);
|
||||
void AddClassFilter(UObject* Owner, FName PropertyName, TSubclassOf<UObject> AllowedClass);
|
||||
void AddEnumFilter(UObject* Owner, FName PropertyName, UEnum* AllowedEnum);
|
||||
void AddNativeEnumFilter(UObject* Owner, FName PropertyName, const FString& AllowedEnumName);
|
||||
void AddIntFilter(UObject* Owner, FName PropertyName);
|
||||
void AddFloatFilter(UObject* Owner, FName PropertyName);
|
||||
void AddBoolFilter(UObject* Owner, FName PropertyName);
|
||||
void AddVectorFilter(UObject* Owner, FName PropertyName);
|
||||
void AddRotatorFilter(UObject* Owner, FName PropertyName);
|
||||
void AddStringFilter(UObject* Owner, FName PropertyName);
|
||||
void AddNameFilter(UObject* Owner, FName PropertyName);
|
||||
|
||||
FORCEINLINE bool IsNone() const { return bNoneIsAllowedValue && SelectedKeyID == FBlackboard::InvalidKey; }
|
||||
FORCEINLINE bool IsSet() const { return SelectedKeyID != FBlackboard::InvalidKey; }
|
||||
FORCEINLINE bool NeedsResolving() const { return SelectedKeyID == FBlackboard::InvalidKey && SelectedKeyName.IsNone() == false; }
|
||||
FORCEINLINE void InvalidateResolvedKey() { SelectedKeyID = FBlackboard::InvalidKey; }
|
||||
|
||||
friend FBlackboardDecoratorDetails;
|
||||
|
||||
UE_DEPRECATED(4.24, "This version of AddClassFilter is deprecated. Please provide AllowedClass as TSubclassOf<UObject>")
|
||||
void AddClassFilter(UObject* Owner, FName PropertyName, TSubclassOf<UClass> AllowedClass);
|
||||
};
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBehaviorTreeTypes : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
static FString BTLoggingContext;
|
||||
|
||||
public:
|
||||
|
||||
static FString DescribeNodeHelper(const UBTNode* Node);
|
||||
|
||||
static FString DescribeNodeResult(EBTNodeResult::Type NodeResult);
|
||||
static FString DescribeFlowAbortMode(EBTFlowAbortMode::Type FlowAbortMode);
|
||||
static FString DescribeActiveNode(EBTActiveNode::Type ActiveNodeType);
|
||||
static FString DescribeTaskStatus(EBTTaskStatus::Type TaskStatus);
|
||||
static FString DescribeNodeUpdateMode(EBTNodeUpdateMode::Type UpdateMode);
|
||||
|
||||
/** returns short name of object's class (BTTaskNode_Wait -> Wait) */
|
||||
static FString GetShortTypeName(const UObject* Ob);
|
||||
|
||||
static FString GetBTLoggingContext() { return BTLoggingContext; }
|
||||
|
||||
// @param NewBTLoggingContext the object which name's will be added to some of the BT logging
|
||||
// pass nullptr to clear
|
||||
static void SetBTLoggingContext(const UBTNode* NewBTLoggingContext);
|
||||
};
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Bool.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Class.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Enum.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Float.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Int.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Name.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_NativeEnum.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Object.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Rotator.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_String.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType_Vector.h"
|
||||
#include "BehaviorTree/BlackboardComponent.h"
|
||||
-242
@@ -1,242 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BlackboardKeyType.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
namespace EBlackboardCompare
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Less = -1,
|
||||
Equal = 0,
|
||||
Greater = 1,
|
||||
|
||||
NotEqual = 1, // important, do not change
|
||||
};
|
||||
}
|
||||
|
||||
namespace EBlackboardKeyOperation
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Basic,
|
||||
Arithmetic,
|
||||
Text,
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EBasicKeyOperation
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Set UMETA(DisplayName="Is Set"),
|
||||
NotSet UMETA(DisplayName="Is Not Set"),
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EArithmeticKeyOperation
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Equal UMETA(DisplayName="Is Equal To"),
|
||||
NotEqual UMETA(DisplayName="Is Not Equal To"),
|
||||
Less UMETA(DisplayName="Is Less Than"),
|
||||
LessOrEqual UMETA(DisplayName="Is Less Than Or Equal To"),
|
||||
Greater UMETA(DisplayName="Is Greater Than"),
|
||||
GreaterOrEqual UMETA(DisplayName="Is Greater Than Or Equal To"),
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace ETextKeyOperation
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Equal UMETA(DisplayName="Is Equal To"),
|
||||
NotEqual UMETA(DisplayName="Is Not Equal To"),
|
||||
Contain UMETA(DisplayName="Contains"),
|
||||
NotContain UMETA(DisplayName="Not Contains"),
|
||||
};
|
||||
}
|
||||
|
||||
struct FBlackboardInstancedKeyMemory
|
||||
{
|
||||
/** index of instanced key in UBlackboardComponent::InstancedKeys */
|
||||
int32 KeyIdx;
|
||||
};
|
||||
|
||||
UCLASS(EditInlineNew, Abstract, CollapseCategories, AutoExpandCategories=(Blackboard))
|
||||
class AIMODULE_API UBlackboardKeyType : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** handle dynamic data size */
|
||||
virtual void PreInitialize(UBlackboardComponent& OwnerComp);
|
||||
|
||||
/** handle instancing if needed */
|
||||
void InitializeKey(UBlackboardComponent& OwnerComp, FBlackboard::FKey KeyID);
|
||||
|
||||
/** does it match settings in filter? */
|
||||
virtual bool IsAllowedByFilter(UBlackboardKeyType* FilterOb) const;
|
||||
|
||||
/** extract location from entry, supports instanced keys */
|
||||
bool WrappedGetLocation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, FVector& Location) const;
|
||||
|
||||
/** extract rotation from entry, supports instanced keys */
|
||||
bool WrappedGetRotation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, FRotator& Rotation) const;
|
||||
|
||||
/** free value before removing from blackboard, supports instanced keys */
|
||||
void WrappedFree(UBlackboardComponent& OwnerComp, uint8* MemoryBlock);
|
||||
|
||||
/** sets value to the default, supports instanced keys */
|
||||
void WrappedClear(const UBlackboardComponent& OwnerComp, uint8* MemoryBlock) const;
|
||||
|
||||
/** check if key has stored value, supports instanced keys */
|
||||
bool WrappedIsEmpty(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
|
||||
/** various value testing, used by decorators, supports instanced keys */
|
||||
bool WrappedTestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const;
|
||||
bool WrappedTestArithmeticOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EArithmeticKeyOperation::Type Op, int32 OtherIntValue, float OtherFloatValue) const;
|
||||
bool WrappedTestTextOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, ETextKeyOperation::Type Op, const FString& OtherString) const;
|
||||
|
||||
/** describe params of arithmetic test */
|
||||
virtual FString DescribeArithmeticParam(int32 IntValue, float FloatValue) const;
|
||||
|
||||
/** convert value to text, supports instanced keys */
|
||||
FString WrappedDescribeValue(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
|
||||
/** description of params for property view */
|
||||
virtual FString DescribeSelf() const;
|
||||
|
||||
/** create replacement key for deprecated data */
|
||||
virtual UBlackboardKeyType* UpdateDeprecatedKey();
|
||||
|
||||
/** @return key instance if bCreateKeyInstance was set */
|
||||
const UBlackboardKeyType* GetKeyInstance(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
UBlackboardKeyType* GetKeyInstance(UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
|
||||
/** compares two values */
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const;
|
||||
|
||||
/** @return true if key wants to be instanced */
|
||||
bool HasInstance() const;
|
||||
|
||||
/** @return true if this object is instanced key */
|
||||
bool IsInstanced() const;
|
||||
|
||||
/** get ValueSize */
|
||||
uint16 GetValueSize() const;
|
||||
|
||||
/** get test supported by this type */
|
||||
EBlackboardKeyOperation::Type GetTestOperation() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** size of value for this type */
|
||||
uint16 ValueSize;
|
||||
|
||||
/** decorator operation supported with this type */
|
||||
TEnumAsByte<EBlackboardKeyOperation::Type> SupportedOp;
|
||||
|
||||
/** set automatically for node instances */
|
||||
uint8 bIsInstanced : 1;
|
||||
|
||||
/** if set, key will be instanced instead of using memory block */
|
||||
uint8 bCreateKeyInstance : 1;
|
||||
|
||||
/** helper function for reading typed data from memory block */
|
||||
template<typename T>
|
||||
static T GetValueFromMemory(const uint8* MemoryBlock)
|
||||
{
|
||||
return *((T*)MemoryBlock);
|
||||
}
|
||||
|
||||
/** helper function for writing typed data to memory block, returns true if value has changed */
|
||||
template<typename T>
|
||||
static bool SetValueInMemory(uint8* MemoryBlock, const T& Value)
|
||||
{
|
||||
const bool bChanged = *((T*)MemoryBlock) != Value;
|
||||
*((T*)MemoryBlock) = Value;
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
/** helper function for witting weak object data to memory block, returns true if value has changed */
|
||||
template<typename T>
|
||||
static bool SetWeakObjectInMemory(uint8* MemoryBlock, const TWeakObjectPtr<T>& Value)
|
||||
{
|
||||
TWeakObjectPtr<T>* PrevValue = (TWeakObjectPtr<T>*)MemoryBlock;
|
||||
const bool bChanged =
|
||||
(Value.IsValid(false, true) != PrevValue->IsValid(false, true)) ||
|
||||
(Value.IsStale(false, true) != PrevValue->IsStale(false, true)) ||
|
||||
(*PrevValue) != Value;
|
||||
|
||||
*((TWeakObjectPtr<T>*)MemoryBlock) = Value;
|
||||
|
||||
return bChanged;
|
||||
}
|
||||
|
||||
friend UBlackboardComponent;
|
||||
|
||||
/** copy value from other key, works directly on provided memory/properties */
|
||||
virtual void CopyValues(UBlackboardComponent& OwnerComp, uint8* MemoryBlock, const UBlackboardKeyType* SourceKeyOb, const uint8* SourceBlock);
|
||||
|
||||
/** initialize memory, works directly on provided memory/properties */
|
||||
virtual void InitializeMemory(UBlackboardComponent& OwnerComp, uint8* MemoryBlock);
|
||||
|
||||
/** free value before removing from blackboard, works directly on provided memory/properties */
|
||||
virtual void FreeMemory(UBlackboardComponent& OwnerComp, uint8* MemoryBlock);
|
||||
|
||||
/** extract location from entry, works directly on provided memory/properties */
|
||||
virtual bool GetLocation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, FVector& Location) const;
|
||||
|
||||
/** extract rotation from entry, works directly on provided memory/properties */
|
||||
virtual bool GetRotation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, FRotator& Rotation) const;
|
||||
|
||||
/** sets value to the default, works directly on provided memory/properties */
|
||||
virtual void Clear(UBlackboardComponent& OwnerComp, uint8* MemoryBlock);
|
||||
|
||||
/** check if key has stored value, works directly on provided memory/properties */
|
||||
virtual bool IsEmpty(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
|
||||
/** various value testing, works directly on provided memory/properties */
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const;
|
||||
virtual bool TestArithmeticOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EArithmeticKeyOperation::Type Op, int32 OtherIntValue, float OtherFloatValue) const;
|
||||
virtual bool TestTextOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, ETextKeyOperation::Type Op, const FString& OtherString) const;
|
||||
|
||||
/** convert value to text, works directly on provided memory/properties */
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE uint16 UBlackboardKeyType::GetValueSize() const
|
||||
{
|
||||
return ValueSize;
|
||||
}
|
||||
|
||||
FORCEINLINE EBlackboardKeyOperation::Type UBlackboardKeyType::GetTestOperation() const
|
||||
{
|
||||
return SupportedOp;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBlackboardKeyType::HasInstance() const
|
||||
{
|
||||
return bCreateKeyInstance;
|
||||
}
|
||||
|
||||
FORCEINLINE bool UBlackboardKeyType::IsInstanced() const
|
||||
{
|
||||
return bIsInstanced;
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Bool.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Bool"))
|
||||
class AIMODULE_API UBlackboardKeyType_Bool : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef bool FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static bool GetValue(const UBlackboardKeyType_Bool* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Bool* KeyOb, uint8* RawData, bool bValue);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const override;
|
||||
};
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Class.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Class"))
|
||||
class AIMODULE_API UBlackboardKeyType_Class : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef UClass* FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditDefaultsOnly, meta=(AllowAbstract="1"))
|
||||
UClass* BaseClass;
|
||||
|
||||
static UClass* GetValue(const UBlackboardKeyType_Class* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Class* KeyOb, uint8* RawData, UClass* Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
virtual FString DescribeSelf() const override;
|
||||
virtual bool IsAllowedByFilter(UBlackboardKeyType* FilterOb) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const override;
|
||||
};
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Enum.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Enum"))
|
||||
class AIMODULE_API UBlackboardKeyType_Enum : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef uint8 FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditDefaultsOnly)
|
||||
UEnum* EnumType;
|
||||
|
||||
/** name of enum defined in c++ code, will take priority over asset from EnumType property */
|
||||
UPROPERTY(Category=Blackboard, EditDefaultsOnly)
|
||||
FString EnumName;
|
||||
|
||||
/** set when EnumName override is valid and active */
|
||||
UPROPERTY(Category = Blackboard, VisibleDefaultsOnly)
|
||||
uint32 bIsEnumNameValid : 1;
|
||||
|
||||
static uint8 GetValue(const UBlackboardKeyType_Enum* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Enum* KeyOb, uint8* RawData, uint8 Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
virtual FString DescribeSelf() const override;
|
||||
virtual FString DescribeArithmeticParam(int32 IntValue, float FloatValue) const override;
|
||||
virtual bool IsAllowedByFilter(UBlackboardKeyType* FilterOb) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestArithmeticOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EArithmeticKeyOperation::Type Op, int32 OtherIntValue, float OtherFloatValue) const override;
|
||||
};
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Float.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Float"))
|
||||
class AIMODULE_API UBlackboardKeyType_Float : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef float FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static float GetValue(const UBlackboardKeyType_Float* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Float* KeyOb, uint8* RawData, float Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
virtual FString DescribeArithmeticParam(int32 IntValue, float FloatValue) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestArithmeticOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EArithmeticKeyOperation::Type Op, int32 OtherIntValue, float OtherFloatValue) const override;
|
||||
};
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Int.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Int"))
|
||||
class AIMODULE_API UBlackboardKeyType_Int : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef int32 FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static int32 GetValue(const UBlackboardKeyType_Int* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Int* KeyOb, uint8* RawData, int32 Value);
|
||||
|
||||
virtual FString DescribeArithmeticParam(int32 IntValue, float FloatValue) const override;
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestArithmeticOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EArithmeticKeyOperation::Type Op, int32 OtherIntValue, float OtherFloatValue) const override;
|
||||
};
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Name.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Name"))
|
||||
class AIMODULE_API UBlackboardKeyType_Name : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FName FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static FName GetValue(const UBlackboardKeyType_Name* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Name* KeyOb, uint8* RawData, const FName& Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestTextOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, ETextKeyOperation::Type Op, const FString& OtherString) const override;
|
||||
};
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_NativeEnum.generated.h"
|
||||
|
||||
// DEPRECATED, please use UBlackboardKeyType_Enum instead
|
||||
|
||||
UCLASS(NotEditInlineNew, HideDropDown)
|
||||
class AIMODULE_API UBlackboardKeyType_NativeEnum : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef uint8 FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditDefaultsOnly)
|
||||
FString EnumName;
|
||||
|
||||
UPROPERTY()
|
||||
UEnum* EnumType;
|
||||
|
||||
virtual UBlackboardKeyType* UpdateDeprecatedKey() override;
|
||||
|
||||
static uint8 GetValue(const UBlackboardKeyType_NativeEnum* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_NativeEnum* KeyOb, uint8* RawData, uint8 Value);
|
||||
};
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Object.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Object"))
|
||||
class AIMODULE_API UBlackboardKeyType_Object : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef UObject* FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditDefaultsOnly, meta=(AllowAbstract="1"))
|
||||
UClass* BaseClass;
|
||||
|
||||
static UObject* GetValue(const UBlackboardKeyType_Object* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Object* KeyOb, uint8* RawData, UObject* Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
virtual FString DescribeSelf() const override;
|
||||
virtual bool IsAllowedByFilter(UBlackboardKeyType* FilterOb) const override;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool GetLocation(const UBlackboardComponent& OwnerComp, const uint8* RawData, FVector& Location) const override;
|
||||
virtual bool GetRotation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, FRotator& Rotation) const override;
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const override;
|
||||
};
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Rotator.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Rotator"))
|
||||
class AIMODULE_API UBlackboardKeyType_Rotator : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FRotator FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static FRotator GetValue(const UBlackboardKeyType_Rotator* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Rotator* KeyOb, uint8* RawData, const FRotator& Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
protected:
|
||||
virtual void InitializeMemory(UBlackboardComponent& OwnerComp, uint8* RawData) override;
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool GetRotation(const UBlackboardComponent& OwnerComp, const uint8* RawData, FRotator& Rotation) const override;
|
||||
virtual bool IsEmpty(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual void Clear(UBlackboardComponent& OwnerComp, uint8* RawData) override;
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const override;
|
||||
};
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_String.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="String"))
|
||||
class AIMODULE_API UBlackboardKeyType_String : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FString FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static FString GetValue(const UBlackboardKeyType_String* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_String* KeyOb, uint8* RawData, const FString& Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
UPROPERTY()
|
||||
FString StringValue;
|
||||
|
||||
protected:
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool TestTextOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, ETextKeyOperation::Type Op, const FString& OtherString) const override;
|
||||
virtual void Clear(UBlackboardComponent& OwnerComp, uint8* MemoryBlock) override;
|
||||
virtual bool IsEmpty(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const override;
|
||||
virtual void CopyValues(UBlackboardComponent& OwnerComp, uint8* MemoryBlock, const UBlackboardKeyType* SourceKeyOb, const uint8* SourceBlock) override;
|
||||
};
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BlackboardKeyType_Vector.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Vector"))
|
||||
class AIMODULE_API UBlackboardKeyType_Vector : public UBlackboardKeyType
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FVector FDataType;
|
||||
static const FDataType InvalidValue;
|
||||
|
||||
static FVector GetValue(const UBlackboardKeyType_Vector* KeyOb, const uint8* RawData);
|
||||
static bool SetValue(UBlackboardKeyType_Vector* KeyOb, uint8* RawData, const FVector& Value);
|
||||
|
||||
virtual EBlackboardCompare::Type CompareValues(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock,
|
||||
const UBlackboardKeyType* OtherKeyOb, const uint8* OtherMemoryBlock) const override;
|
||||
|
||||
protected:
|
||||
virtual void InitializeMemory(UBlackboardComponent& OwnerComp, uint8* RawData) override;
|
||||
virtual FString DescribeValue(const UBlackboardComponent& OwnerComp, const uint8* RawData) const override;
|
||||
virtual bool GetLocation(const UBlackboardComponent& OwnerComp, const uint8* RawData, FVector& Location) const override;
|
||||
virtual bool IsEmpty(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock) const override;
|
||||
virtual void Clear(UBlackboardComponent& OwnerComp, uint8* MemoryBlock) override;
|
||||
virtual bool TestBasicOperation(const UBlackboardComponent& OwnerComp, const uint8* MemoryBlock, EBasicKeyOperation::Type Op) const override;
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "BlackboardAssetProvider.generated.h"
|
||||
|
||||
|
||||
/** Helper interface to allow FBlackboardKeySelector properties on DataAssets (and more).
|
||||
* Used by FBlackboardSelectorDetails to access the related Blackboard based on UObject
|
||||
* hierarchy. The asset containing the Blackboard should broadcast OnBlackboardOwnerChanged
|
||||
* when ever the asset ptr changes. */
|
||||
UINTERFACE(Blueprintable, MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
|
||||
class UBlackboardAssetProvider : public UInterface
|
||||
{
|
||||
GENERATED_UINTERFACE_BODY()
|
||||
};
|
||||
|
||||
class AIMODULE_API IBlackboardAssetProvider
|
||||
{
|
||||
GENERATED_IINTERFACE_BODY()
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** Delegate to be called by class implementing IBlackboardAssetProvider when the property containing the returned BlackboardData is changed (i.e. on PostEditChangeProperty). */
|
||||
DECLARE_MULTICAST_DELEGATE_TwoParams(FBlackboardOwnerChanged, UObject* /*AssetOwner*/, UBlackboardData* /*Asset*/);
|
||||
static FBlackboardOwnerChanged OnBlackboardOwnerChanged;
|
||||
#endif
|
||||
/** Returns BlackboardData referenced by the owner object. */
|
||||
UFUNCTION(BlueprintCallable, Category = GameplayTags)
|
||||
virtual UBlackboardData* GetBlackboardAsset() const PURE_VIRTUAL(IBlackboardAssetProvider::GetBlackboardAsset, return nullptr; );
|
||||
};
|
||||
|
||||
|
||||
@@ -1,490 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
/**
|
||||
* Blackboard - holds AI's world knowledge, easily accessible for behavior trees
|
||||
*
|
||||
* Properties are stored in byte array, and should be accessed only though
|
||||
* GetValue* / SetValue* functions. They will handle broadcasting change events
|
||||
* for registered observers.
|
||||
*
|
||||
* Keys are defined by BlackboardData data asset.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "AISystem.h"
|
||||
#include "BehaviorTree/BlackboardData.h"
|
||||
#include "BlackboardComponent.generated.h"
|
||||
|
||||
class UBrainComponent;
|
||||
|
||||
namespace EBlackboardDescription
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
OnlyValue,
|
||||
KeyWithValue,
|
||||
DetailedKeyWithValue,
|
||||
Full,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
UCLASS(ClassGroup = AI, meta = (BlueprintSpawnableComponent), hidecategories = (Sockets, Collision))
|
||||
class AIMODULE_API UBlackboardComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UBlackboardComponent(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
/** BEGIN UActorComponent overrides */
|
||||
virtual void InitializeComponent() override;
|
||||
virtual void UninitializeComponent() override;
|
||||
/** END UActorComponent overrides */
|
||||
|
||||
/** @return name of key */
|
||||
FName GetKeyName(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return key ID from name */
|
||||
FBlackboard::FKey GetKeyID(const FName& KeyName) const;
|
||||
|
||||
/** @return class of value for given key */
|
||||
TSubclassOf<UBlackboardKeyType> GetKeyType(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return true if the key is marked as instance synced */
|
||||
bool IsKeyInstanceSynced(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return number of entries in data asset */
|
||||
int32 GetNumKeys() const;
|
||||
|
||||
/** @return true if blackboard have valid data asset */
|
||||
bool HasValidAsset() const;
|
||||
|
||||
/** register observer for blackboard key */
|
||||
FDelegateHandle RegisterObserver(FBlackboard::FKey KeyID, UObject* NotifyOwner, FOnBlackboardChangeNotification ObserverDelegate);
|
||||
|
||||
/** unregister observer from blackboard key */
|
||||
void UnregisterObserver(FBlackboard::FKey KeyID, FDelegateHandle ObserverHandle);
|
||||
|
||||
/** unregister all observers associated with given owner */
|
||||
void UnregisterObserversFrom(UObject* NotifyOwner);
|
||||
|
||||
/** pause observer change notifications, any new ones will be added to a queue */
|
||||
void PauseObserverNotifications();
|
||||
|
||||
/** resume observer change notifications and, optionally, process the queued observation list */
|
||||
void ResumeObserverNotifications(bool bSendQueuedObserverNotifications);
|
||||
|
||||
/** pause change notifies and add them to queue */
|
||||
UE_DEPRECATED(4.15, "Please call PauseObserverUpdates.")
|
||||
void PauseUpdates();
|
||||
|
||||
/** resume change notifies and process queued list */
|
||||
UE_DEPRECATED(4.15, "Please call ResumeObserverNotifications.")
|
||||
void ResumeUpdates();
|
||||
|
||||
/** @return associated behavior tree component */
|
||||
UBrainComponent* GetBrainComponent() const;
|
||||
|
||||
/** @return blackboard data asset */
|
||||
UBlackboardData* GetBlackboardAsset() const;
|
||||
|
||||
/** caches UBrainComponent pointer to be used in communication */
|
||||
void CacheBrainComponent(UBrainComponent& BrainComponent);
|
||||
|
||||
/** setup component for using given blackboard asset, returns true if blackboard is properly initialized for specified blackboard data */
|
||||
bool InitializeBlackboard(UBlackboardData& NewAsset);
|
||||
|
||||
/** @return true if component can be used with specified blackboard asset */
|
||||
bool IsCompatibleWith(UBlackboardData* TestAsset) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
UObject* GetValueAsObject(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
UClass* GetValueAsClass(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
uint8 GetValueAsEnum(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
int32 GetValueAsInt(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
float GetValueAsFloat(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
bool GetValueAsBool(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
FString GetValueAsString(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
FName GetValueAsName(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
FVector GetValueAsVector(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
FRotator GetValueAsRotator(const FName& KeyName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsObject(const FName& KeyName, UObject* ObjectValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsClass(const FName& KeyName, UClass* ClassValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsEnum(const FName& KeyName, uint8 EnumValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsInt(const FName& KeyName, int32 IntValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsFloat(const FName& KeyName, float FloatValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsBool(const FName& KeyName, bool BoolValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsString(const FName& KeyName, FString StringValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsName(const FName& KeyName, FName NameValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
void SetValueAsVector(const FName& KeyName, FVector VectorValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Components|Blackboard")
|
||||
void SetValueAsRotator(const FName& KeyName, FRotator VectorValue);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard", Meta=(
|
||||
Tooltip="If the vector value has been set (and not cleared), this function returns true (indicating that the value should be valid). If it's not set, the vector value is invalid and this function will return false. (Also returns false if the key specified does not hold a vector.)"))
|
||||
bool IsVectorValueSet(const FName& KeyName) const;
|
||||
bool IsVectorValueSet(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** return false if call failed (most probably no such entry in BB) */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
bool GetLocationFromEntry(const FName& KeyName, FVector& ResultLocation) const;
|
||||
bool GetLocationFromEntry(FBlackboard::FKey KeyID, FVector& ResultLocation) const;
|
||||
|
||||
/** return false if call failed (most probably no such entry in BB) */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
|
||||
bool GetRotationFromEntry(const FName& KeyName, FRotator& ResultRotation) const;
|
||||
bool GetRotationFromEntry(FBlackboard::FKey KeyID, FRotator& ResultRotation) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Components|Blackboard")
|
||||
void ClearValue(const FName& KeyName);
|
||||
void ClearValue(FBlackboard::FKey KeyID);
|
||||
|
||||
/** Copy content from SourceKeyID to DestinationID and return true if it worked */
|
||||
bool CopyKeyValue(FBlackboard::FKey SourceKeyID, FBlackboard::FKey DestinationID);
|
||||
|
||||
template<class TDataClass>
|
||||
bool IsKeyOfType(FBlackboard::FKey KeyID) const;
|
||||
|
||||
template<class TDataClass>
|
||||
bool SetValue(const FName& KeyName, typename TDataClass::FDataType Value);
|
||||
|
||||
template<class TDataClass>
|
||||
bool SetValue(FBlackboard::FKey KeyID, typename TDataClass::FDataType Value);
|
||||
|
||||
template<class TDataClass>
|
||||
typename TDataClass::FDataType GetValue(const FName& KeyName) const;
|
||||
|
||||
template<class TDataClass>
|
||||
typename TDataClass::FDataType GetValue(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** get pointer to raw data for given key */
|
||||
FORCEINLINE uint8* GetKeyRawData(const FName& KeyName) { return GetKeyRawData(GetKeyID(KeyName)); }
|
||||
FORCEINLINE uint8* GetKeyRawData(FBlackboard::FKey KeyID) { return ValueMemory.Num() && ValueOffsets.IsValidIndex(KeyID) ? (ValueMemory.GetData() + ValueOffsets[KeyID]) : NULL; }
|
||||
|
||||
FORCEINLINE const uint8* GetKeyRawData(const FName& KeyName) const { return GetKeyRawData(GetKeyID(KeyName)); }
|
||||
FORCEINLINE const uint8* GetKeyRawData(FBlackboard::FKey KeyID) const { return ValueMemory.Num() && ValueOffsets.IsValidIndex(KeyID) ? (ValueMemory.GetData() + ValueOffsets[KeyID]) : NULL; }
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS // re BlackboardAsset
|
||||
FORCEINLINE bool IsValidKey(FBlackboard::FKey KeyID) const { check(BlackboardAsset); return KeyID != FBlackboard::InvalidKey && BlackboardAsset->Keys.IsValidIndex(KeyID); }
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS // re BlackboardAsset
|
||||
|
||||
/** compares blackboard's values under specified keys */
|
||||
EBlackboardCompare::Type CompareKeyValues(TSubclassOf<UBlackboardKeyType> KeyType, FBlackboard::FKey KeyA, FBlackboard::FKey KeyB) const;
|
||||
|
||||
FString GetDebugInfoString(EBlackboardDescription::Type Mode) const;
|
||||
|
||||
/** get description of value under given key */
|
||||
FString DescribeKeyValue(const FName& KeyName, EBlackboardDescription::Type Mode) const;
|
||||
FString DescribeKeyValue(FBlackboard::FKey KeyID, EBlackboardDescription::Type Mode) const;
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
/** prepare blackboard snapshot for logs */
|
||||
virtual void DescribeSelfToVisLog(struct FVisualLogEntry* Snapshot) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
/** cached behavior tree component */
|
||||
UPROPERTY(transient)
|
||||
UBrainComponent* BrainComp;
|
||||
|
||||
/** data asset defining entries. Will be used as part of InitializeComponent
|
||||
* call provided BlackboardAsset hasn't been already set (via a InitializeBlackboard
|
||||
* call). */
|
||||
UPROPERTY(EditDefaultsOnly, Category = AI)
|
||||
UBlackboardData* DefaultBlackboardAsset;
|
||||
|
||||
/** internal use, current BB asset being used. Will be made private in the future */
|
||||
UE_DEPRECATED_FORGAME(4.26, "Directly accessing BlackboardAsset is not longer supported. Use DefaultBlackboardAsset or InitializeBlackboard to set it and GetBlackboardAsset to retrieve it")
|
||||
UPROPERTY(transient)
|
||||
UBlackboardData* BlackboardAsset;
|
||||
|
||||
/** memory block holding all values */
|
||||
TArray<uint8> ValueMemory;
|
||||
|
||||
/** offsets in ValueMemory for each key */
|
||||
TArray<uint16> ValueOffsets;
|
||||
|
||||
/** instanced keys with custom data allocations */
|
||||
UPROPERTY(transient)
|
||||
TArray<UBlackboardKeyType*> KeyInstances;
|
||||
|
||||
protected:
|
||||
struct FOnBlackboardChangeNotificationInfo
|
||||
{
|
||||
FOnBlackboardChangeNotificationInfo(const FOnBlackboardChangeNotification& InDelegateHandle)
|
||||
: DelegateHandle(InDelegateHandle)
|
||||
{
|
||||
}
|
||||
|
||||
FDelegateHandle GetHandle() const
|
||||
{
|
||||
return DelegateHandle.GetHandle();
|
||||
}
|
||||
|
||||
FOnBlackboardChangeNotification DelegateHandle;
|
||||
bool bToBeRemoved = false;
|
||||
};
|
||||
|
||||
|
||||
/** Count of re-entrant observer notifications */
|
||||
mutable int32 NotifyObserversRecursionCount = 0;
|
||||
|
||||
/** Count of observers to remove */
|
||||
mutable int32 ObserversToRemoveCount = 0;
|
||||
|
||||
/** observers registered for blackboard keys */
|
||||
mutable TMultiMap<uint8, FOnBlackboardChangeNotificationInfo> Observers;
|
||||
|
||||
/** observers registered from owner objects */
|
||||
mutable TMultiMap<UObject*, FDelegateHandle> ObserverHandles;
|
||||
|
||||
/** queued key change notification, will be processed on ResumeUpdates call */
|
||||
mutable TArray<uint8> QueuedUpdates;
|
||||
|
||||
/** set when observation notifies are paused and shouldn't be passed to observers */
|
||||
uint32 bPausedNotifies : 1;
|
||||
|
||||
/** reset to false every time a new BB asset is assigned to this component */
|
||||
uint32 bSynchronizedKeyPopulated : 1;
|
||||
|
||||
/** notifies behavior tree decorators about change in blackboard */
|
||||
void NotifyObservers(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** initializes parent chain in asset */
|
||||
void InitializeParentChain(UBlackboardData* NewAsset);
|
||||
|
||||
/** destroy allocated values */
|
||||
void DestroyValues();
|
||||
|
||||
/** populates BB's synchronized entries */
|
||||
void PopulateSynchronizedKeys();
|
||||
|
||||
bool ShouldSyncWithBlackboard(UBlackboardComponent& OtherBlackboardComponent) const;
|
||||
|
||||
friend UBlackboardKeyType;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS // re BlackboardAsset
|
||||
|
||||
FORCEINLINE bool UBlackboardComponent::HasValidAsset() const
|
||||
{
|
||||
return BlackboardAsset && BlackboardAsset->IsValid();
|
||||
}
|
||||
|
||||
template<class TDataClass>
|
||||
bool UBlackboardComponent::IsKeyOfType(FBlackboard::FKey KeyID) const
|
||||
{
|
||||
const FBlackboardEntry* EntryInfo = BlackboardAsset ? BlackboardAsset->GetKey(KeyID) : nullptr;
|
||||
return (EntryInfo != nullptr) && (EntryInfo->KeyType != nullptr) && (EntryInfo->KeyType->GetClass() == TDataClass::StaticClass());
|
||||
}
|
||||
|
||||
template<class TDataClass>
|
||||
bool UBlackboardComponent::SetValue(const FName& KeyName, typename TDataClass::FDataType Value)
|
||||
{
|
||||
const FBlackboard::FKey KeyID = GetKeyID(KeyName);
|
||||
return SetValue<TDataClass>(KeyID, Value);
|
||||
}
|
||||
|
||||
template<class TDataClass>
|
||||
bool UBlackboardComponent::SetValue(FBlackboard::FKey KeyID, typename TDataClass::FDataType Value)
|
||||
{
|
||||
const FBlackboardEntry* EntryInfo = BlackboardAsset ? BlackboardAsset->GetKey(KeyID) : nullptr;
|
||||
if ((EntryInfo == nullptr) || (EntryInfo->KeyType == nullptr) || (EntryInfo->KeyType->GetClass() != TDataClass::StaticClass()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint16 DataOffset = EntryInfo->KeyType->HasInstance() ? sizeof(FBlackboardInstancedKeyMemory) : 0;
|
||||
uint8* RawData = GetKeyRawData(KeyID) + DataOffset;
|
||||
if (RawData)
|
||||
{
|
||||
UBlackboardKeyType* KeyOb = EntryInfo->KeyType->HasInstance() ? KeyInstances[KeyID] : EntryInfo->KeyType;
|
||||
const bool bChanged = TDataClass::SetValue((TDataClass*)KeyOb, RawData, Value);
|
||||
if (bChanged)
|
||||
{
|
||||
NotifyObservers(KeyID);
|
||||
if (BlackboardAsset->HasSynchronizedKeys() && IsKeyInstanceSynced(KeyID))
|
||||
{
|
||||
UAISystem* AISystem = UAISystem::GetCurrentSafe(GetWorld());
|
||||
for (auto Iter = AISystem->CreateBlackboardDataToComponentsIterator(*BlackboardAsset); Iter; ++Iter)
|
||||
{
|
||||
UBlackboardComponent* OtherBlackboard = Iter.Value();
|
||||
if (OtherBlackboard != nullptr && ShouldSyncWithBlackboard(*OtherBlackboard))
|
||||
{
|
||||
UBlackboardData* const OtherBlackboardAsset = OtherBlackboard->GetBlackboardAsset();
|
||||
const int32 OtherKeyID = OtherBlackboardAsset ? OtherBlackboardAsset->GetKeyID(EntryInfo->EntryName) : FBlackboard::InvalidKey;
|
||||
if (OtherKeyID != FBlackboard::InvalidKey)
|
||||
{
|
||||
UBlackboardKeyType* OtherKeyOb = EntryInfo->KeyType->HasInstance() ? OtherBlackboard->KeyInstances[OtherKeyID] : EntryInfo->KeyType;
|
||||
uint8* OtherRawData = OtherBlackboard->GetKeyRawData(OtherKeyID) + DataOffset;
|
||||
|
||||
TDataClass::SetValue((TDataClass*)OtherKeyOb, OtherRawData, Value);
|
||||
OtherBlackboard->NotifyObservers(OtherKeyID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class TDataClass>
|
||||
typename TDataClass::FDataType UBlackboardComponent::GetValue(const FName& KeyName) const
|
||||
{
|
||||
const FBlackboard::FKey KeyID = GetKeyID(KeyName);
|
||||
return GetValue<TDataClass>(KeyID);
|
||||
}
|
||||
|
||||
template<class TDataClass>
|
||||
typename TDataClass::FDataType UBlackboardComponent::GetValue(FBlackboard::FKey KeyID) const
|
||||
{
|
||||
const FBlackboardEntry* EntryInfo = BlackboardAsset ? BlackboardAsset->GetKey(KeyID) : nullptr;
|
||||
if ((EntryInfo == nullptr) || (EntryInfo->KeyType == nullptr) || (EntryInfo->KeyType->GetClass() != TDataClass::StaticClass()))
|
||||
{
|
||||
return TDataClass::InvalidValue;
|
||||
}
|
||||
|
||||
UBlackboardKeyType* KeyOb = EntryInfo->KeyType->HasInstance() ? KeyInstances[KeyID] : EntryInfo->KeyType;
|
||||
const uint16 DataOffset = EntryInfo->KeyType->HasInstance() ? sizeof(FBlackboardInstancedKeyMemory) : 0;
|
||||
|
||||
const uint8* RawData = GetKeyRawData(KeyID) + DataOffset;
|
||||
return RawData ? TDataClass::GetValue((TDataClass*)KeyOb, RawData) : TDataClass::InvalidValue;
|
||||
}
|
||||
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS // re BlackboardAsset
|
||||
|
||||
/**
|
||||
* A helper type that improved performance of reading data from BB
|
||||
* It's meant for a specific use-case:
|
||||
|
||||
* 1. you have a logical property you want to use both in C++ code
|
||||
* as well as being reflected in the BB
|
||||
* 2. you only ever set this property in native code
|
||||
*
|
||||
* If those two are true then add a member variable of type FBlackboardCachedAccessor
|
||||
* like so:
|
||||
|
||||
* FBlackboardCachedAccessor<UBlackboardKeyType_Bool> BBEnemyInMeleeRangeKey;
|
||||
|
||||
* and from this point on whenever you set or read the value use this variable.
|
||||
* This will make reading almost free.
|
||||
*
|
||||
* Before you use the variable you need to initialize it with appropriate BB asset.
|
||||
* This is best done in AAIController::InitializeBlackboard override, like so:
|
||||
*
|
||||
* const FBlackboard::FKey EnemyInMeleeRangeKey = BlackboardAsset.GetKeyID(TEXT("EnemyInMeleeRange"));
|
||||
* BBEnemyInMeleeRangeKey = FBlackboardCachedAccessor<UBlackboardKeyType_Bool>(BlackboardComp, EnemyInMeleeRangeKey);
|
||||
*
|
||||
* Best used with numerical and boolean types. No guarantees made when using pointer types.
|
||||
|
||||
* @note does not automatically support BB component or asset change */
|
||||
template<typename TBlackboardKey>
|
||||
struct FBBKeyCachedAccessor
|
||||
{
|
||||
private:
|
||||
FBlackboard::FKey BBKey;
|
||||
typedef typename TBlackboardKey::FDataType FStoredType;
|
||||
FStoredType CachedValue;
|
||||
public:
|
||||
FBBKeyCachedAccessor() : BBKey(FBlackboard::InvalidKey), CachedValue(TBlackboardKey::InvalidValue)
|
||||
{}
|
||||
|
||||
FBBKeyCachedAccessor(UBlackboardComponent& BBComponent, FBlackboard::FKey InBBKey)
|
||||
{
|
||||
ensure(InBBKey != FBlackboard::InvalidKey);
|
||||
if (ensure(BBComponent.IsKeyOfType<TBlackboardKey>(InBBKey)))
|
||||
{
|
||||
BBKey = InBBKey;
|
||||
CachedValue = BBComponent.GetValue<TBlackboardKey>(InBBKey);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
FORCEINLINE bool SetValue(UBlackboardComponent& BBComponent, const T2 InValue)
|
||||
{
|
||||
return SetValue(BBComponent, FStoredType(InValue));
|
||||
}
|
||||
|
||||
/** @return True is value has changed*/
|
||||
FORCEINLINE bool SetValue(UBlackboardComponent& BBComponent, const FStoredType InValue)
|
||||
{
|
||||
ensure(BBKey != FBlackboard::InvalidKey);
|
||||
if (InValue != CachedValue)
|
||||
{
|
||||
CachedValue = InValue;
|
||||
BBComponent.SetValue<TBlackboardKey>(BBKey, InValue);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FORCEINLINE const FStoredType& Get() const
|
||||
{
|
||||
ensure(BBKey != FBlackboard::InvalidKey);
|
||||
return CachedValue;
|
||||
}
|
||||
|
||||
template<typename T2>
|
||||
FORCEINLINE T2 Get() const
|
||||
{
|
||||
ensure(BBKey != FBlackboard::InvalidKey);
|
||||
return (T2)CachedValue;
|
||||
}
|
||||
|
||||
bool IsValid() const { return BBKey != FBlackboard::InvalidKey; }
|
||||
};
|
||||
@@ -1,181 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "BlackboardData.generated.h"
|
||||
|
||||
/** blackboard entry definition */
|
||||
USTRUCT()
|
||||
struct FBlackboardEntry
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FName EntryName;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard, Meta=(ToolTip="Optional description to explain what this blackboard entry does."))
|
||||
FString EntryDescription;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
/** key type and additional properties */
|
||||
UPROPERTY(EditAnywhere, Instanced, Category=Blackboard)
|
||||
UBlackboardKeyType* KeyType;
|
||||
|
||||
/** if set to true then this field will be synchronized across all instances of this blackboard */
|
||||
UPROPERTY(EditAnywhere, Category = Blackboard)
|
||||
uint32 bInstanceSynced : 1;
|
||||
|
||||
FBlackboardEntry()
|
||||
: KeyType(nullptr), bInstanceSynced(0)
|
||||
{}
|
||||
|
||||
bool operator==(const FBlackboardEntry& Other) const;
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType, AutoExpandCategories=(Blackboard))
|
||||
class AIMODULE_API UBlackboardData : public UDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FKeyUpdate, UBlackboardData* /*asset*/);
|
||||
|
||||
/** parent blackboard (keys can be overridden) */
|
||||
UPROPERTY(EditAnywhere, Category=Parent)
|
||||
UBlackboardData* Parent;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** all keys inherited from parent chain */
|
||||
UPROPERTY(VisibleDefaultsOnly, Transient, Category=Parent)
|
||||
TArray<FBlackboardEntry> ParentKeys;
|
||||
#endif
|
||||
|
||||
/** blackboard keys */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
TArray<FBlackboardEntry> Keys;
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
uint32 bHasSynchronizedKeys : 1;
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE bool HasSynchronizedKeys() const { return bHasSynchronizedKeys; }
|
||||
|
||||
/** @return true if the key is instance synced */
|
||||
bool IsKeyInstanceSynced(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return key ID from name */
|
||||
FBlackboard::FKey GetKeyID(const FName& KeyName) const;
|
||||
|
||||
/** @return name of key */
|
||||
FName GetKeyName(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return class of value for given key */
|
||||
TSubclassOf<UBlackboardKeyType> GetKeyType(FBlackboard::FKey KeyID) const;
|
||||
|
||||
/** @return number of defined keys, including parent chain */
|
||||
int32 GetNumKeys() const;
|
||||
|
||||
FORCEINLINE FBlackboard::FKey GetFirstKeyID() const { return FirstKeyID; }
|
||||
|
||||
/** @return key data */
|
||||
const FBlackboardEntry* GetKey(FBlackboard::FKey KeyID) const;
|
||||
|
||||
const TArray<FBlackboardEntry>& GetKeys() const { return Keys; }
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
virtual void PostLoad() override;
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif
|
||||
void PropagateKeyChangesToDerivedBlackboardAssets();
|
||||
|
||||
/** @return true if blackboard keys are not conflicting with parent key chain */
|
||||
bool IsValid() const;
|
||||
|
||||
/** updates persistent key with given name, depending on currently defined entries and parent chain
|
||||
* @return key type of newly created entry for further setup
|
||||
*/
|
||||
template<class T>
|
||||
T* UpdatePersistentKey(const FName& KeyName)
|
||||
{
|
||||
T* CreatedKeyType = NULL;
|
||||
|
||||
const FBlackboard::FKey KeyID = InternalGetKeyID(KeyName, DontCheckParentKeys);
|
||||
if (KeyID == FBlackboard::InvalidKey && Parent == NULL)
|
||||
{
|
||||
FBlackboardEntry Entry;
|
||||
Entry.EntryName = KeyName;
|
||||
|
||||
CreatedKeyType = NewObject<T>(this);
|
||||
Entry.KeyType = CreatedKeyType;
|
||||
|
||||
Keys.Add(Entry);
|
||||
MarkPackageDirty();
|
||||
PropagateKeyChangesToDerivedBlackboardAssets();
|
||||
}
|
||||
else if (KeyID != FBlackboard::InvalidKey && Parent != NULL)
|
||||
{
|
||||
const FBlackboard::FKey KeyIndex = KeyID - FirstKeyID;
|
||||
Keys.RemoveAt(KeyIndex);
|
||||
MarkPackageDirty();
|
||||
PropagateKeyChangesToDerivedBlackboardAssets();
|
||||
}
|
||||
|
||||
return CreatedKeyType;
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** A delegate called on PostEditChangeProperty. Can be used in editor to react to asset changes. */
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FBlackboardDataChanged, UBlackboardData* /*Asset*/);
|
||||
static FBlackboardDataChanged OnBlackboardDataChanged;
|
||||
#endif
|
||||
|
||||
/** delegate called for every loaded blackboard asset
|
||||
* meant for adding game specific persistent keys */
|
||||
static FKeyUpdate OnUpdateKeys;
|
||||
|
||||
/** updates parent key cache for editor */
|
||||
void UpdateParentKeys();
|
||||
|
||||
/** forces update of FirstKeyID, which depends on parent chain */
|
||||
void UpdateKeyIDs();
|
||||
|
||||
void UpdateIfHasSynchronizedKeys();
|
||||
|
||||
/** fix entries with deprecated key types */
|
||||
void UpdateDeprecatedKeys();
|
||||
|
||||
/** returns true if OtherAsset is somewhere up the parent chain of this asset. Node that it will return false if *this == OtherAsset */
|
||||
bool IsChildOf(const UBlackboardData& OtherAsset) const;
|
||||
|
||||
/** returns true if OtherAsset is equal to *this, or is it's parent, or *this is OtherAsset's parent */
|
||||
bool IsRelatedTo(const UBlackboardData& OtherAsset) const
|
||||
{
|
||||
return this == &OtherAsset || IsChildOf(OtherAsset) || OtherAsset.IsChildOf(*this)
|
||||
|| (Parent && OtherAsset.Parent && Parent->IsRelatedTo(*OtherAsset.Parent));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
enum EKeyLookupMode
|
||||
{
|
||||
CheckParentKeys,
|
||||
DontCheckParentKeys,
|
||||
};
|
||||
|
||||
/** @return first ID for keys of this asset (parent keys goes first) */
|
||||
FBlackboard::FKey FirstKeyID;
|
||||
|
||||
/** @return key ID from name */
|
||||
FBlackboard::FKey InternalGetKeyID(const FName& KeyName, EKeyLookupMode LookupMode) const;
|
||||
|
||||
/** check if parent chain contains given blackboard data */
|
||||
UE_DEPRECATED(4.14, "This function is deprecated, please use IsChildOf instead.")
|
||||
bool HasParent(const UBlackboardData* TestParent) const;
|
||||
};
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTCompositeNode.h"
|
||||
#include "BTComposite_Selector.generated.h"
|
||||
|
||||
/**
|
||||
* Selector composite node.
|
||||
* Selector Nodes execute their children from left to right, and will stop executing its children when one of their children succeeds.
|
||||
* If a Selector's child succeeds, the Selector succeeds. If all the Selector's children fail, the Selector fails.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTComposite_Selector: public UBTCompositeNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual int32 GetNextChildHandler(struct FBehaviorTreeSearchData& SearchData, int32 PrevChild, EBTNodeResult::Type LastResult) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif
|
||||
};
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTCompositeNode.h"
|
||||
#include "BTComposite_Sequence.generated.h"
|
||||
|
||||
/**
|
||||
* Sequence composite node.
|
||||
* Sequence Nodes execute their children from left to right, and will stop executing its children when one of their children fails.
|
||||
* If a child fails, then the Sequence fails. If all the Sequence's children succeed, then the Sequence succeeds.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTComposite_Sequence : public UBTCompositeNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual int32 GetNextChildHandler(struct FBehaviorTreeSearchData& SearchData, int32 PrevChild, EBTNodeResult::Type LastResult) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual bool CanAbortLowerPriority() const override;
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif
|
||||
};
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTCompositeNode.h"
|
||||
#include "BTComposite_SimpleParallel.generated.h"
|
||||
|
||||
namespace EBTParallelChild
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
MainTask,
|
||||
BackgroundTree,
|
||||
};
|
||||
}
|
||||
|
||||
UENUM()
|
||||
namespace EBTParallelMode
|
||||
{
|
||||
// keep in sync with DescribeFinishMode
|
||||
|
||||
enum Type
|
||||
{
|
||||
AbortBackground UMETA(DisplayName="Immediate" , ToolTip="When main task finishes, immediately abort background tree."),
|
||||
WaitForBackground UMETA(DisplayName="Delayed" , ToolTip="When main task finishes, wait for background tree to finish."),
|
||||
};
|
||||
}
|
||||
|
||||
struct FBTParallelMemory : public FBTCompositeMemory
|
||||
{
|
||||
/** last Id of search, detect infinite loops when there isn't any valid task in background tree */
|
||||
int32 LastSearchId;
|
||||
|
||||
/** finish result of main task */
|
||||
TEnumAsByte<EBTNodeResult::Type> MainTaskResult;
|
||||
|
||||
/** set when main task is running */
|
||||
uint8 bMainTaskIsActive : 1;
|
||||
|
||||
/** try running background tree task even if main task has finished */
|
||||
uint8 bForceBackgroundTree : 1;
|
||||
|
||||
/** set when main task needs to be repeated */
|
||||
uint8 bRepeatMainTask : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple Parallel composite node.
|
||||
* Allows for running two children: one which must be a single task node (with optional decorators), and the other of which can be a complete subtree.
|
||||
*/
|
||||
UCLASS(HideCategories=(Composite))
|
||||
class AIMODULE_API UBTComposite_SimpleParallel : public UBTCompositeNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** how background tree should be handled when main task finishes execution */
|
||||
UPROPERTY(EditInstanceOnly, Category = Parallel)
|
||||
TEnumAsByte<EBTParallelMode::Type> FinishMode;
|
||||
|
||||
/** handle child updates */
|
||||
virtual int32 GetNextChildHandler(FBehaviorTreeSearchData& SearchData, int32 PrevChild, EBTNodeResult::Type LastResult) const override;
|
||||
|
||||
virtual void NotifyChildExecution(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const override;
|
||||
virtual void NotifyNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult) const override;
|
||||
virtual bool CanNotifyDecoratorsOnDeactivation(FBehaviorTreeSearchData& SearchData, int32 ChildIdx, EBTNodeResult::Type& NodeResult) const override;
|
||||
virtual bool CanPushSubtree(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, int32 ChildIdx) const override;
|
||||
virtual void SetChildOverride(FBehaviorTreeSearchData& SearchData, int8 Index) const override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
|
||||
/** helper for showing values of EBTParallelMode enum */
|
||||
static FString DescribeFinishMode(EBTParallelMode::Type Mode);
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual bool CanAbortLowerPriority() const override;
|
||||
virtual bool CanAbortSelf() const override;
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/Decorators/BTDecorator_BlackboardBase.h"
|
||||
#include "BehaviorTree/Blackboard/BlackboardKeyType.h"
|
||||
#include "BTDecorator_Blackboard.generated.h"
|
||||
|
||||
class FBlackboardDecoratorDetails;
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
|
||||
/**
|
||||
* Decorator for accessing blackboard values
|
||||
*/
|
||||
|
||||
UENUM()
|
||||
namespace EBTBlackboardRestart
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
ValueChange UMETA(DisplayName="On Value Change", ToolTip="Restart on every change of observed blackboard value"),
|
||||
ResultChange UMETA(DisplayName="On Result Change", ToolTip="Restart only when result of evaluated condition is changed"),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Blackboard decorator node.
|
||||
* A decorator node that bases its condition on a Blackboard key.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_Blackboard : public UBTDecorator_BlackboardBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID) override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
protected:
|
||||
|
||||
/** value for arithmetic operations */
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Value"))
|
||||
int32 IntValue;
|
||||
|
||||
/** value for arithmetic operations */
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Value"))
|
||||
float FloatValue;
|
||||
|
||||
/** value for string operations */
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Value"))
|
||||
FString StringValue;
|
||||
|
||||
/** cached description */
|
||||
UPROPERTY()
|
||||
FString CachedDescription;
|
||||
|
||||
/** operation type */
|
||||
UPROPERTY()
|
||||
uint8 OperationType;
|
||||
|
||||
/** when observer can try to request abort? */
|
||||
UPROPERTY(Category=FlowControl, EditAnywhere)
|
||||
TEnumAsByte<EBTBlackboardRestart::Type> NotifyObserver;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Query"))
|
||||
TEnumAsByte<EBasicKeyOperation::Type> BasicOperation;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Query"))
|
||||
TEnumAsByte<EArithmeticKeyOperation::Type> ArithmeticOperation;
|
||||
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta=(DisplayName="Key Query"))
|
||||
TEnumAsByte<ETextKeyOperation::Type> TextOperation;
|
||||
|
||||
#endif
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
||||
/** describe decorator and cache it */
|
||||
virtual void BuildDescription();
|
||||
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
#endif
|
||||
|
||||
/** take blackboard value and evaluate decorator's condition */
|
||||
bool EvaluateOnBlackboard(const UBlackboardComponent& BlackboardComp) const;
|
||||
|
||||
friend FBlackboardDecoratorDetails;
|
||||
};
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_BlackboardBase.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTDecorator_BlackboardBase : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** initialize any asset related data */
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
/** notify about change in blackboard keys */
|
||||
virtual EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif
|
||||
|
||||
/** get name of selected blackboard key */
|
||||
FName GetSelectedBlackboardKey() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector BlackboardKey;
|
||||
|
||||
/** called when execution flow controller becomes active */
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
/** called when execution flow controller becomes inactive */
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE FName UBTDecorator_BlackboardBase::GetSelectedBlackboardKey() const
|
||||
{
|
||||
return BlackboardKey.SelectedKeyName;
|
||||
}
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_BlueprintBase.generated.h"
|
||||
|
||||
class AActor;
|
||||
class AAIController;
|
||||
class APawn;
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
|
||||
/**
|
||||
* Base class for blueprint based decorator nodes. Do NOT use it for creating native c++ classes!
|
||||
*
|
||||
* Unlike task and services, decorator have two execution chains:
|
||||
* ExecutionStart-ExecutionFinish and ObserverActivated-ObserverDeactivated
|
||||
* which makes automatic latent action cleanup impossible. Keep in mind, that
|
||||
* you HAVE TO verify is given chain is still active after resuming from any
|
||||
* latent action (like Delay, Timelines, etc).
|
||||
*
|
||||
* Helper functions:
|
||||
* - IsDecoratorExecutionActive (true after ExecutionStart, until ExecutionFinish)
|
||||
* - IsDecoratorObserverActive (true after ObserverActivated, until ObserverDeactivated)
|
||||
*/
|
||||
|
||||
UCLASS(Abstract, Blueprintable)
|
||||
class AIMODULE_API UBTDecorator_BlueprintBase : public UBTDecorator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UBTDecorator_BlueprintBase(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
/** initialize data about blueprint defined properties */
|
||||
void InitializeProperties();
|
||||
|
||||
/** setup node name */
|
||||
virtual void PostInitProperties() override;
|
||||
virtual void PostLoad() override;
|
||||
|
||||
/** notify about changes in blackboard */
|
||||
EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override final;
|
||||
virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp) override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
/** return if this decorator should abort in current circumstances */
|
||||
bool GetShouldAbort(UBehaviorTreeComponent& OwnerComp) const;
|
||||
|
||||
virtual void SetOwner(AActor* ActorOwner) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
virtual bool UsesBlueprint() const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** Cached AIController owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AAIController* AIOwner;
|
||||
|
||||
/** Cached AIController owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AActor* ActorOwner;
|
||||
|
||||
/** blackboard key names that should be observed */
|
||||
UPROPERTY()
|
||||
TArray<FName> ObservedKeyNames;
|
||||
|
||||
/** properties with runtime values, stored only in class default object */
|
||||
TArray<FProperty*> PropertyData;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Description)
|
||||
FString CustomDescription;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
/** show detailed information about properties */
|
||||
UPROPERTY(EditInstanceOnly, Category=Description)
|
||||
uint32 bShowPropertyDetails : 1;
|
||||
|
||||
/** Applies only if Decorator has any FBlackboardKeySelector property and if decorator is
|
||||
* set to abort BT flow. Is set to true ReceiveConditionCheck will be called only on changes
|
||||
* to observed BB keys. If false or no BB keys observed ReceiveConditionCheck will be called every tick */
|
||||
UPROPERTY(EditDefaultsOnly, Category = "FlowControl", AdvancedDisplay)
|
||||
uint32 bCheckConditionOnlyBlackBoardChanges : 1;
|
||||
|
||||
/** gets set to true if decorator declared BB keys it can potentially observe */
|
||||
UPROPERTY()
|
||||
uint32 bIsObservingBB : 1;
|
||||
|
||||
/** set if ReceiveTick is implemented by blueprint */
|
||||
uint32 ReceiveTickImplementations : 2;
|
||||
|
||||
/** set if ReceiveExecutionStart is implemented by blueprint */
|
||||
uint32 ReceiveExecutionStartImplementations : 2;
|
||||
|
||||
/** set if ReceiveExecutionFinish is implemented by blueprint */
|
||||
uint32 ReceiveExecutionFinishImplementations : 2;
|
||||
|
||||
/** set if ReceiveObserverActivated is implemented by blueprint */
|
||||
uint32 ReceiveObserverActivatedImplementations : 2;
|
||||
|
||||
/** set if ReceiveObserverDeactivated is implemented by blueprint */
|
||||
uint32 ReceiveObserverDeactivatedImplementations : 2;
|
||||
|
||||
/** set if ReceiveConditionCheck is implemented by blueprint */
|
||||
uint32 PerformConditionCheckImplementations : 2;
|
||||
|
||||
bool CalculateRawConditionValueImpl(UBehaviorTreeComponent& OwnerComp) const;
|
||||
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnNodeActivation(FBehaviorTreeSearchData& SearchData) override;
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
|
||||
/** tick function
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveTick(AActor* OwnerActor, float DeltaSeconds);
|
||||
|
||||
/** called on execution of underlying node
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveExecutionStart(AActor* OwnerActor);
|
||||
|
||||
/** called when execution of underlying node is finished
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveExecutionFinish(AActor* OwnerActor, enum EBTNodeResult::Type NodeResult);
|
||||
|
||||
/** called when observer is activated (flow controller)
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveObserverActivated(AActor* OwnerActor);
|
||||
|
||||
/** called when observer is deactivated (flow controller)
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveObserverDeactivated(AActor* OwnerActor);
|
||||
|
||||
/** called when testing if underlying node can be executed, must call FinishConditionCheck
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
bool PerformConditionCheck(AActor* OwnerActor);
|
||||
|
||||
/** Alternative AI version of ReceiveTick
|
||||
* @see ReceiveTick for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveTickAI(AAIController* OwnerController, APawn* ControlledPawn, float DeltaSeconds);
|
||||
|
||||
/** Alternative AI version of ReceiveExecutionStart
|
||||
* @see ReceiveExecutionStart for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveExecutionStartAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveExecutionFinish
|
||||
* @see ReceiveExecutionFinish for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveExecutionFinishAI(AAIController* OwnerController, APawn* ControlledPawn, enum EBTNodeResult::Type NodeResult);
|
||||
|
||||
/** Alternative AI version of ReceiveObserverActivated
|
||||
* @see ReceiveObserverActivated for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveObserverActivatedAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveObserverDeactivated
|
||||
* @see ReceiveObserverDeactivated for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveObserverDeactivatedAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveConditionCheck
|
||||
* @see ReceiveConditionCheck for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
bool PerformConditionCheckAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** check if decorator is part of currently active branch */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
bool IsDecoratorExecutionActive() const;
|
||||
|
||||
/** check if decorator's observer is currently active */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
bool IsDecoratorObserverActive() const;
|
||||
|
||||
FORCEINLINE bool GetNeedsTickForConditionChecking() const { return PerformConditionCheckImplementations != 0 && (bIsObservingBB == false || bCheckConditionOnlyBlackBoardChanges == false); }
|
||||
};
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_CheckGameplayTagsOnActor.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* GameplayTag decorator node.
|
||||
* A decorator node that bases its condition on whether the specified Actor (in the blackboard) has a Gameplay Tag or
|
||||
* Tags specified.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTDecorator_CheckGameplayTagsOnActor : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=GameplayTagCheck,
|
||||
Meta=(ToolTips="Which Actor (from the blackboard) should be checked for these gameplay tags?"))
|
||||
struct FBlackboardKeySelector ActorToCheck;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=GameplayTagCheck)
|
||||
EGameplayContainerMatchType TagsToMatch;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=GameplayTagCheck)
|
||||
FGameplayTagContainer GameplayTags;
|
||||
|
||||
/** cached description */
|
||||
UPROPERTY()
|
||||
FString CachedDescription;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** describe decorator and cache it */
|
||||
virtual void BuildDescription();
|
||||
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
};
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_CompareBBEntries.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
|
||||
UENUM()
|
||||
namespace EBlackBoardEntryComparison
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Equal UMETA(DisplayName="Is Equal To"),
|
||||
NotEqual UMETA(DisplayName="Is Not Equal To")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Blackboard comparison decorator node.
|
||||
* A decorator node that bases its condition on a comparison between two Blackboard keys.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_CompareBBEntries : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
|
||||
/** operation type */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
TEnumAsByte<EBlackBoardEntryComparison::Type> Operator;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector BlackboardKeyA;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector BlackboardKeyB;
|
||||
|
||||
public:
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
virtual EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/Decorators/BTDecorator_Blackboard.h"
|
||||
#include "BTDecorator_ConditionalLoop.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
/**
|
||||
* Conditional loop decorator node.
|
||||
* A decorator node that loops execution as long as condition is satisfied.
|
||||
*/
|
||||
UCLASS(HideCategories=(FlowControl))
|
||||
class AIMODULE_API UBTDecorator_ConditionalLoop : public UBTDecorator_Blackboard
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID) override;
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_ConeCheck.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
|
||||
struct FBTConeCheckDecoratorMemory
|
||||
{
|
||||
bool bLastRawResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cone check decorator node.
|
||||
* A decorator node that bases its condition on a cone check, using Blackboard entries to form the parameters of the check.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTDecorator_ConeCheck : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FBTConeCheckDecoratorMemory TNodeInstanceMemory;
|
||||
|
||||
/** Angle between cone direction and code cone edge, or a half of the total cone angle */
|
||||
UPROPERTY(Category=Decorator, EditAnywhere)
|
||||
float ConeHalfAngle;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector ConeOrigin;
|
||||
|
||||
/** "None" means "use ConeOrigin's direction" */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector ConeDirection;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector Observed;
|
||||
|
||||
float ConeHalfAngleDot;
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
void OnBlackboardChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
|
||||
bool CalculateDirection(const UBlackboardComponent* BlackboardComp, const FBlackboardKeySelector& Origin, const FBlackboardKeySelector& End, FVector& Direction) const;
|
||||
|
||||
private:
|
||||
bool CalcConditionImpl(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const;
|
||||
};
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_Cooldown.generated.h"
|
||||
|
||||
struct FBTCooldownDecoratorMemory
|
||||
{
|
||||
float LastUseTimestamp;
|
||||
uint8 bRequestedRestart : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cooldown decorator node.
|
||||
* A decorator node that bases its condition on whether a cooldown timer has expired.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_Cooldown : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** max allowed time for execution of underlying node */
|
||||
UPROPERTY(Category=Decorator, EditAnywhere)
|
||||
float CoolDownTime;
|
||||
|
||||
//~ Begin UObject Interface
|
||||
virtual void PostLoad() override;
|
||||
//~ End UObject Interface
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual void InitializeMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryInit::Type InitType) const override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
};
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "NavFilters/NavigationQueryFilter.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_DoesPathExist.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
UENUM()
|
||||
namespace EPathExistanceQueryType
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NavmeshRaycast2D UMETA(ToolTip = "Really Fast"),
|
||||
HierarchicalQuery UMETA(ToolTip = "Fast"),
|
||||
RegularPathFinding UMETA(ToolTip = "Slow"),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Cooldown decorator node.
|
||||
* A decorator node that bases its condition on whether a path exists between two points from the Blackboard.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTDecorator_DoesPathExist : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Condition)
|
||||
FBlackboardKeySelector BlackboardKeyA;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Condition)
|
||||
FBlackboardKeySelector BlackboardKeyB;
|
||||
|
||||
public:
|
||||
|
||||
// deprecated, set value of blackboard key A on initialization
|
||||
UPROPERTY()
|
||||
uint32 bUseSelf:1;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=Condition)
|
||||
TEnumAsByte<EPathExistanceQueryType::Type> PathQueryType;
|
||||
|
||||
/** "None" will result in default filter being used */
|
||||
UPROPERTY(Category=Node, EditAnywhere)
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass;
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_ForceSuccess.generated.h"
|
||||
|
||||
/**
|
||||
* Change node result to Success
|
||||
* useful for creating optional branches in sequence
|
||||
*
|
||||
* Forcing failed result was not implemented, because it doesn't make sense in both basic composites:
|
||||
* - sequence = child nodes behind it will be never run
|
||||
* - selector = would allow executing multiple nodes, turning it into a sequence...
|
||||
*/
|
||||
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_ForceSuccess : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnNodeProcessed(struct FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type& NodeResult) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
#include "AITypes.h"
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "DataProviders/AIDataProvider.h"
|
||||
#include "BehaviorTree/Decorators/BTDecorator_BlackboardBase.h"
|
||||
#include "BTDecorator_IsAtLocation.generated.h"
|
||||
|
||||
/**
|
||||
* Is At Location decorator node.
|
||||
* A decorator node that checks if AI controlled pawn is at given location.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTDecorator_IsAtLocation : public UBTDecorator_BlackboardBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** distance threshold to accept as being at location */
|
||||
UPROPERTY(EditAnywhere, Category = Condition, meta = (ClampMin = "0.0", EditCondition = "!bUseParametrizedRadius"))
|
||||
float AcceptableRadius;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Condition, meta = (EditCondition = "bUseParametrizedRadius"))
|
||||
FAIDataProviderFloatValue ParametrizedAcceptableRadius;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Condition, meta = (EditCondition = "!bPathFindingBasedTest"))
|
||||
FAIDistanceType GeometricDistanceType;
|
||||
|
||||
UPROPERTY()
|
||||
uint32 bUseParametrizedRadius : 1;
|
||||
|
||||
/** if moving to an actor and this actor is a nav agent, then we will move to their nav agent location */
|
||||
UPROPERTY(EditAnywhere, Category = Condition, meta = (EditCondition = "bPathFindingBasedTest"))
|
||||
uint32 bUseNavAgentGoalLocation : 1;
|
||||
|
||||
/** If true the result will be consistent with tests done while following paths.
|
||||
* Set to false to use geometric distance as configured with DistanceType */
|
||||
UPROPERTY(EditAnywhere, Category = Condition)
|
||||
uint32 bPathFindingBasedTest : 1;
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
float GetGeometricDistanceSquared(const FVector& A, const FVector& B) const;
|
||||
};
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "BehaviorTree/Decorators/BTDecorator_BlackboardBase.h"
|
||||
#include "BTDecorator_IsBBEntryOfClass.generated.h"
|
||||
|
||||
class UBlackboardComponent;
|
||||
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_IsBBEntryOfClass : public UBTDecorator_BlackboardBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UBTDecorator_IsBBEntryOfClass(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(Category = Blackboard, EditAnywhere)
|
||||
TSubclassOf<UObject> TestClass;
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID) override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
};
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BehaviorTreeTypes.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_KeepInCone.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
struct FBTKeepInConeDecoratorMemory
|
||||
{
|
||||
FVector InitialDirection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cooldown decorator node.
|
||||
* A decorator node that bases its condition on whether the observed position is still inside a cone. The cone's direction is calculated when the node first becomes relevant.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_KeepInCone : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
typedef FBTKeepInConeDecoratorMemory TNodeInstanceMemory;
|
||||
|
||||
/** max allowed time for execution of underlying node */
|
||||
UPROPERTY(Category=Decorator, EditAnywhere)
|
||||
float ConeHalfAngle;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector ConeOrigin;
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
FBlackboardKeySelector Observed;
|
||||
|
||||
// deprecated, set value of ConeOrigin on initialization
|
||||
UPROPERTY()
|
||||
uint32 bUseSelfAsOrigin:1;
|
||||
|
||||
// deprecated, set value of Observed on initialization
|
||||
UPROPERTY()
|
||||
uint32 bUseSelfAsObserved:1;
|
||||
|
||||
float ConeHalfAngleDot;
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
|
||||
bool CalculateCurrentDirection(const UBehaviorTreeComponent& OwnerComp, FVector& Direction) const;
|
||||
};
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_Loop.generated.h"
|
||||
|
||||
struct FBTLoopDecoratorMemory
|
||||
{
|
||||
int32 SearchId;
|
||||
uint8 RemainingExecutions;
|
||||
float TimeStarted;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loop decorator node.
|
||||
* A decorator node that bases its condition on whether its loop counter has been exceeded.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_Loop : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** number of executions */
|
||||
UPROPERTY(Category=Decorator, EditAnywhere, meta=(EditCondition="!bInfiniteLoop"))
|
||||
int32 NumLoops;
|
||||
|
||||
/** infinite loop */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
bool bInfiniteLoop;
|
||||
|
||||
/** timeout (when looping infinitely, when we finish a loop we will check whether we have spent this time looping, if we have we will stop looping). A negative value means loop forever. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere, meta = (EditCondition = "bInfiniteLoop"))
|
||||
float InfiniteLoopTimeoutTime;
|
||||
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnNodeActivation(FBehaviorTreeSearchData& SearchData) override;
|
||||
};
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_ReachedMoveGoal.generated.h"
|
||||
|
||||
/**
|
||||
* Reached Move Goal decorator node.
|
||||
* A decorator node that bases its condition on whether the AI controller's path following component returns that it has reached its goal.
|
||||
*/
|
||||
UCLASS(meta = (DeprecatedNode, DeprecationMessage = "Please use IsAtLocation decorator instead."))
|
||||
class AIMODULE_API UBTDecorator_ReachedMoveGoal : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_SetTagCooldown.generated.h"
|
||||
|
||||
/**
|
||||
* Set tag cooldown decorator node.
|
||||
* A decorator node that sets a gameplay tag cooldown.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_SetTagCooldown : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** Gameplay tag that will be used for the cooldown. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
FGameplayTag CooldownTag;
|
||||
|
||||
/** Value we will add or set to the Cooldown tag when this task runs. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
float CooldownDuration;
|
||||
|
||||
/** True if we are adding to any existing duration, false if we are setting the duration (potentially invalidating an existing end time). */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
bool bAddToExistingDuration;
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) override;
|
||||
};
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_TagCooldown.generated.h"
|
||||
|
||||
struct FBTTagCooldownDecoratorMemory
|
||||
{
|
||||
uint8 bRequestedRestart : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cooldown decorator node.
|
||||
* A decorator node that bases its condition on whether a cooldown timer based on a gameplay tag has expired.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_TagCooldown : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** Gameplay tag that will be used for the cooldown. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
FGameplayTag CooldownTag;
|
||||
|
||||
/** Value we will add or set to the Cooldown tag when this node is deactivated. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere, meta = (EditCondition = "bActivatesCooldown"))
|
||||
float CooldownDuration;
|
||||
|
||||
/** True if we are adding to any existing duration, false if we are setting the duration (potentially invalidating an existing end time). */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere, meta = (EditCondition = "bActivatesCooldown"))
|
||||
bool bAddToExistingDuration;
|
||||
|
||||
/** Whether or not we are adding/setting to the cooldown tag's value when the decorator deactivates. */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere, meta = (DisplayName = "Adds/Sets Cooldown on Deactivation"))
|
||||
bool bActivatesCooldown;
|
||||
|
||||
//~ Begin UObject Interface
|
||||
virtual void PostLoad() override;
|
||||
//~ End UObject Interface
|
||||
|
||||
virtual bool CalculateRawConditionValue(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) const override;
|
||||
virtual void InitializeMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryInit::Type InitType) const override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnNodeDeactivation(FBehaviorTreeSearchData& SearchData, EBTNodeResult::Type NodeResult) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
|
||||
private:
|
||||
bool HasCooldownFinished(const UBehaviorTreeComponent& OwnerComp) const;
|
||||
};
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTDecorator.h"
|
||||
#include "BTDecorator_TimeLimit.generated.h"
|
||||
|
||||
/**
|
||||
* Time Limit decorator node.
|
||||
* A decorator node that bases its condition on whether a timer has exceeded a specified value. The timer is reset each time the node becomes relevant.
|
||||
*/
|
||||
UCLASS(HideCategories=(Condition))
|
||||
class AIMODULE_API UBTDecorator_TimeLimit : public UBTDecorator
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** max allowed time for execution of underlying node */
|
||||
UPROPERTY(Category=Decorator, EditAnywhere)
|
||||
float TimeLimit;
|
||||
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
virtual void OnNodeActivation(FBehaviorTreeSearchData& SearchData) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
};
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTService.h"
|
||||
#include "BTService_BlackboardBase.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTService_BlackboardBase : public UBTService
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** initialize any asset related data */
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
/** get name of selected blackboard key */
|
||||
FName GetSelectedBlackboardKey() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
struct FBlackboardKeySelector BlackboardKey;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE FName UBTService_BlackboardBase::GetSelectedBlackboardKey() const
|
||||
{
|
||||
return BlackboardKey.SelectedKeyName;
|
||||
}
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTService.h"
|
||||
#include "BTService_BlueprintBase.generated.h"
|
||||
|
||||
class AActor;
|
||||
class AAIController;
|
||||
class APawn;
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* Base class for blueprint based service nodes. Do NOT use it for creating native c++ classes!
|
||||
*
|
||||
* When service receives Deactivation event, all latent actions associated this instance are being removed.
|
||||
* This prevents from resuming activity started by Activation, but does not handle external events.
|
||||
* Please use them safely (unregister at abort) and call IsServiceActive() when in doubt.
|
||||
*/
|
||||
|
||||
UCLASS(Abstract, Blueprintable)
|
||||
class AIMODULE_API UBTService_BlueprintBase : public UBTService
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp) override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
virtual void SetOwner(AActor* ActorOwner) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual bool UsesBlueprint() const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** Cached AIController owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AAIController* AIOwner;
|
||||
|
||||
/** Cached actor owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AActor* ActorOwner;
|
||||
|
||||
// Gets the description for our service
|
||||
virtual FString GetStaticServiceDescription() const override;
|
||||
|
||||
/** properties with runtime values, stored only in class default object */
|
||||
TArray<FProperty*> PropertyData;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Description)
|
||||
FString CustomDescription;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
/** show detailed information about properties */
|
||||
UPROPERTY(EditInstanceOnly, Category=Description)
|
||||
uint32 bShowPropertyDetails : 1;
|
||||
|
||||
/** show detailed information about implemented events */
|
||||
UPROPERTY(EditInstanceOnly, Category = Description)
|
||||
uint32 bShowEventDetails : 1;
|
||||
|
||||
/** set if ReceiveTick is implemented by blueprint */
|
||||
uint32 ReceiveTickImplementations : 2;
|
||||
|
||||
/** set if ReceiveActivation is implemented by blueprint */
|
||||
uint32 ReceiveActivationImplementations : 2;
|
||||
|
||||
/** set if ReceiveDeactivation is implemented by blueprint */
|
||||
uint32 ReceiveDeactivationImplementations : 2;
|
||||
|
||||
/** set if ReceiveSearchStart is implemented by blueprint */
|
||||
uint32 ReceiveSearchStartImplementations : 2;
|
||||
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
virtual void OnSearchStart(FBehaviorTreeSearchData& SearchData) override;
|
||||
|
||||
/** tick function
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveTick(AActor* OwnerActor, float DeltaSeconds);
|
||||
|
||||
/** task search enters branch of tree
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveSearchStart(AActor* OwnerActor);
|
||||
|
||||
/** service became active
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveActivation(AActor* OwnerActor);
|
||||
|
||||
/** service became inactive
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveDeactivation(AActor* OwnerActor);
|
||||
|
||||
/** Alternative AI version of ReceiveTick function.
|
||||
* @see ReceiveTick for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveTickAI(AAIController* OwnerController, APawn* ControlledPawn, float DeltaSeconds);
|
||||
|
||||
/** Alternative AI version of ReceiveSearchStart function.
|
||||
* @see ReceiveSearchStart for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveSearchStartAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveActivation function.
|
||||
* @see ReceiveActivation for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveActivationAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveDeactivation function.
|
||||
* @see ReceiveDeactivation for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveDeactivationAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** check if service is currently being active */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
bool IsServiceActive() const;
|
||||
};
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "BehaviorTree/Services/BTService_BlackboardBase.h"
|
||||
#include "BTService_DefaultFocus.generated.h"
|
||||
|
||||
class AActor;
|
||||
class UBlackboardComponent;
|
||||
|
||||
struct FBTFocusMemory
|
||||
{
|
||||
AActor* FocusActorSet;
|
||||
FVector FocusLocationSet;
|
||||
bool bActorSet;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
FocusActorSet = nullptr;
|
||||
FocusLocationSet = FAISystem::InvalidLocation;
|
||||
bActorSet = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Default Focus service node.
|
||||
* A service node that automatically sets the AI controller's focus when it becomes active.
|
||||
*/
|
||||
UCLASS(hidecategories=(Service))
|
||||
class AIMODULE_API UBTService_DefaultFocus : public UBTService_BlackboardBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
// not exposed to users on purpose. Here to make reusing focus-setting mechanics by derived classes possible
|
||||
UPROPERTY()
|
||||
uint8 FocusPriority;
|
||||
|
||||
UBTService_DefaultFocus(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual uint16 GetInstanceMemorySize() const override { return sizeof(FBTFocusMemory); }
|
||||
virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
EBlackboardNotificationResult OnBlackboardKeyValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "BehaviorTree/Services/BTService_BlackboardBase.h"
|
||||
#include "BTService_RunEQS.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
struct FBTEQSServiceMemory
|
||||
{
|
||||
/** Query request ID */
|
||||
int32 RequestID;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTService_RunEQS : public UBTService_BlackboardBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
FEQSParametrizedQueryExecutionRequest EQSRequest;
|
||||
|
||||
FQueryFinishedSignature QueryFinishedDelegate;
|
||||
|
||||
public:
|
||||
UBTService_RunEQS(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
virtual void OnCeaseRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void InitializeMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryInit::Type InitType) const override;
|
||||
virtual uint16 GetInstanceMemorySize() const override { return sizeof(FBTEQSServiceMemory); }
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** We need this only for verification, no need to have it in shipped builds */
|
||||
virtual void CleanupMemory(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTMemoryClear::Type CleanupType) const override;
|
||||
/** prepare query params */
|
||||
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
void OnQueryFinished(TSharedPtr<FEnvQueryResult> Result);
|
||||
};
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_BlackboardBase.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTTask_BlackboardBase : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** initialize any asset related data */
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
/** get name of selected blackboard key */
|
||||
FName GetSelectedBlackboardKey() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
struct FBlackboardKeySelector BlackboardKey;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE FName UBTTask_BlackboardBase::GetSelectedBlackboardKey() const
|
||||
{
|
||||
return BlackboardKey.SelectedKeyName;
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_BlueprintBase.generated.h"
|
||||
|
||||
class AActor;
|
||||
class AAIController;
|
||||
class APawn;
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* Base class for blueprint based task nodes. Do NOT use it for creating native c++ classes!
|
||||
*
|
||||
* When task receives Abort event, all latent actions associated this instance are being removed.
|
||||
* This prevents from resuming activity started by Execute, but does not handle external events.
|
||||
* Please use them safely (unregister at abort) and call IsTaskExecuting() when in doubt.
|
||||
*/
|
||||
|
||||
UCLASS(Abstract, Blueprintable)
|
||||
class AIMODULE_API UBTTask_BlueprintBase : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp) override;
|
||||
virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
|
||||
virtual void SetOwner(AActor* ActorOwner) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual bool UsesBlueprint() const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** Cached AIController owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AAIController* AIOwner;
|
||||
|
||||
/** Cached actor owner of BehaviorTreeComponent. */
|
||||
UPROPERTY(Transient)
|
||||
AActor* ActorOwner;
|
||||
|
||||
/** If any of the Tick functions is implemented, how often should they be ticked.
|
||||
* Values < 0 mean 'every tick'. */
|
||||
UPROPERTY(EditAnywhere, Category = Task)
|
||||
FIntervalCountdown TickInterval;
|
||||
|
||||
/** temporary variable for ReceiveExecute(Abort)-FinishExecute(Abort) chain */
|
||||
mutable TEnumAsByte<EBTNodeResult::Type> CurrentCallResult;
|
||||
|
||||
/** properties that should be copied */
|
||||
TArray<FProperty*> PropertyData;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Description)
|
||||
FString CustomDescription;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
/** show detailed information about properties */
|
||||
UPROPERTY(EditInstanceOnly, Category=Description)
|
||||
uint32 bShowPropertyDetails : 1;
|
||||
|
||||
/** set if ReceiveTick is implemented by blueprint */
|
||||
uint32 ReceiveTickImplementations : 2;
|
||||
|
||||
/** set if ReceiveExecute is implemented by blueprint */
|
||||
uint32 ReceiveExecuteImplementations : 2;
|
||||
|
||||
/** set if ReceiveAbort is implemented by blueprint */
|
||||
uint32 ReceiveAbortImplementations : 2;
|
||||
|
||||
/** set when task enters Aborting state */
|
||||
uint32 bIsAborting : 1;
|
||||
|
||||
/** if set, execution is inside blueprint's ReceiveExecute(Abort) event
|
||||
* FinishExecute(Abort) function should store their result in CurrentCallResult variable */
|
||||
mutable uint32 bStoreFinishResult : 1;
|
||||
|
||||
/** entry point, task will stay active until FinishExecute is called.
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveExecute(AActor* OwnerActor);
|
||||
|
||||
/** if blueprint graph contains this event, task will stay active until FinishAbort is called
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveAbort(AActor* OwnerActor);
|
||||
|
||||
/** tick function
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ReceiveTick(AActor* OwnerActor, float DeltaSeconds);
|
||||
|
||||
/** Alternative AI version of ReceiveExecute
|
||||
* @see ReceiveExecute for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveExecuteAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of ReceiveAbort
|
||||
* @see ReceiveAbort for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveAbortAI(AAIController* OwnerController, APawn* ControlledPawn);
|
||||
|
||||
/** Alternative AI version of tick function.
|
||||
* @see ReceiveTick for more details
|
||||
* @Note that if both generic and AI event versions are implemented only the more
|
||||
* suitable one will be called, meaning the AI version if called for AI, generic one otherwise */
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = AI)
|
||||
void ReceiveTickAI(AAIController* OwnerController, APawn* ControlledPawn, float DeltaSeconds);
|
||||
|
||||
/** finishes task execution with Success or Fail result */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
void FinishExecute(bool bSuccess);
|
||||
|
||||
/** aborts task execution */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
void FinishAbort();
|
||||
|
||||
/** task execution will be finished (with result 'Success') after receiving specified message */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
void SetFinishOnMessage(FName MessageName);
|
||||
|
||||
/** task execution will be finished (with result 'Success') after receiving specified message with indicated ID */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
void SetFinishOnMessageWithId(FName MessageName, int32 RequestID = -1);
|
||||
|
||||
/** check if task is currently being executed */
|
||||
UFUNCTION(BlueprintCallable, Category="AI|BehaviorTree")
|
||||
bool IsTaskExecuting() const;
|
||||
|
||||
/** check if task is currently being aborted */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|BehaviorTree")
|
||||
bool IsTaskAborting() const;
|
||||
|
||||
/** ticks this task */
|
||||
virtual void TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
};
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_FinishWithResult.generated.h"
|
||||
|
||||
/**
|
||||
* Instantly finishes with given result
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_FinishWithResult : public UBTTaskNode
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UBTTask_FinishWithResult(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
protected:
|
||||
/** allows adding random time to wait time */
|
||||
UPROPERTY(Category = Result, EditAnywhere)
|
||||
TEnumAsByte<EBTNodeResult::Type> Result;
|
||||
};
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_GameplayTaskBase.generated.h"
|
||||
|
||||
struct FBTGameplayTaskMemory
|
||||
{
|
||||
TWeakObjectPtr<UAITask> Task;
|
||||
uint8 bObserverCanFinishTask : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for managing gameplay tasks
|
||||
* Since AITask doesn't have any kind of success/failed results, default implemenation will only return EBTNode::Succeeded
|
||||
*
|
||||
* In your ExecuteTask:
|
||||
* - use NewBTAITask() helper to create task
|
||||
* - initialize task with values if needed
|
||||
* - use StartGameplayTask() helper to execute and get node result
|
||||
*/
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTTask_GameplayTaskBase : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) override;
|
||||
virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
|
||||
protected:
|
||||
|
||||
/** if set, behavior tree task will wait until gameplay tasks finishes */
|
||||
UPROPERTY(EditAnywhere, Category = Task, AdvancedDisplay)
|
||||
uint32 bWaitForGameplayTask : 1;
|
||||
|
||||
/** start task and initialize FBTGameplayTaskMemory memory block */
|
||||
EBTNodeResult::Type StartGameplayTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, UAITask& Task);
|
||||
|
||||
/** get finish result from task */
|
||||
virtual EBTNodeResult::Type DetermineGameplayTaskResult(UAITask& Task) const;
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_MakeNoise.generated.h"
|
||||
|
||||
/**
|
||||
* Make Noise task node.
|
||||
* A task node that calls MakeNoise() on this Pawn when executed.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_MakeNoise : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** Loudnes of generated noise */
|
||||
UPROPERTY(Category=Node, EditAnywhere, meta=(ClampMin = "0", ClampMax = "1", UIMin = "0", UIMax = "1"))
|
||||
float Loudnes;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_MoveTo.h"
|
||||
#include "BTTask_MoveDirectlyToward.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* Move Directly Toward task node.
|
||||
* Moves the AI pawn toward the specified Actor or Location (Vector) blackboard entry in a straight line, without regard to any navigation system. If you need the AI to navigate, use the "Move To" node instead.
|
||||
*/
|
||||
UCLASS(config=Game)
|
||||
class AIMODULE_API UBTTask_MoveDirectlyToward : public UBTTask_MoveTo
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void PostLoad() override;
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
UE_DEPRECATED_FORGAME(4.12, "This property is now deprecated, use UBTTask_MoveTo::bTrackMovingGoal instead.")
|
||||
UPROPERTY()
|
||||
uint32 bDisablePathUpdateOnGoalLocationChange : 1;
|
||||
|
||||
UE_DEPRECATED_FORGAME(4.12, "This property is now deprecated, use UBTTask_MoveTo::bProjectGoalLocation instead.")
|
||||
UPROPERTY()
|
||||
uint32 bProjectVectorGoalToNavigation : 1;
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY()
|
||||
uint32 bUpdatedDeprecatedProperties : 1;
|
||||
};
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "NavFilters/NavigationQueryFilter.h"
|
||||
#include "AITypes.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
|
||||
#include "BTTask_MoveTo.generated.h"
|
||||
|
||||
class UAITask_MoveTo;
|
||||
class UBlackboardComponent;
|
||||
|
||||
struct FBTMoveToTaskMemory
|
||||
{
|
||||
/** Move request ID */
|
||||
FAIRequestID MoveRequestID;
|
||||
|
||||
FDelegateHandle BBObserverDelegateHandle;
|
||||
FVector PreviousGoalLocation;
|
||||
|
||||
TWeakObjectPtr<UAITask_MoveTo> Task;
|
||||
|
||||
uint8 bWaitingForPath : 1;
|
||||
uint8 bObserverCanFinishTask : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move To task node.
|
||||
* Moves the AI pawn toward the specified Actor or Location blackboard entry using the navigation system.
|
||||
*/
|
||||
UCLASS(config=Game)
|
||||
class AIMODULE_API UBTTask_MoveTo : public UBTTask_BlackboardBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** fixed distance added to threshold between AI and goal location in destination reach test */
|
||||
UPROPERTY(config, Category = Node, EditAnywhere, meta=(ClampMin = "0.0", UIMin="0.0"))
|
||||
float AcceptableRadius;
|
||||
|
||||
/** "None" will result in default filter being used */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
TSubclassOf<UNavigationQueryFilter> FilterClass;
|
||||
|
||||
/** if task is expected to react to changes to location represented by BB key
|
||||
* this property can be used to tweak sensitivity of the mechanism. Value is
|
||||
* recommended to be less than AcceptableRadius */
|
||||
UPROPERTY(Category=Blackboard, EditAnywhere, meta = (ClampMin = "1", UIMin = "1", EditCondition="bObserveBlackboardValue", DisplayAfter="bObserveBlackboardValue"))
|
||||
float ObservedBlackboardValueTolerance;
|
||||
|
||||
/** if move goal in BB changes the move will be redirected to new location */
|
||||
UPROPERTY(Category = Blackboard, EditAnywhere)
|
||||
uint32 bObserveBlackboardValue : 1;
|
||||
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
uint32 bAllowStrafe : 1;
|
||||
|
||||
/** if set, use incomplete path when goal can't be reached */
|
||||
UPROPERTY(Category = Node, EditAnywhere, AdvancedDisplay)
|
||||
uint32 bAllowPartialPath : 1;
|
||||
|
||||
/** if set, path to goal actor will update itself when actor moves */
|
||||
UPROPERTY(Category = Node, EditAnywhere, AdvancedDisplay)
|
||||
uint32 bTrackMovingGoal : 1;
|
||||
|
||||
/** if set, goal location will be projected on navigation data (navmesh) before using */
|
||||
UPROPERTY(Category = Node, EditAnywhere, AdvancedDisplay)
|
||||
uint32 bProjectGoalLocation : 1;
|
||||
|
||||
/** if set, radius of AI's capsule will be added to threshold between AI and goal location in destination reach test */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
uint32 bReachTestIncludesAgentRadius : 1;
|
||||
|
||||
/** if set, radius of goal's capsule will be added to threshold between AI and goal location in destination reach test */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
uint32 bReachTestIncludesGoalRadius : 1;
|
||||
|
||||
/** DEPRECATED, please use combination of bReachTestIncludes*Radius instead */
|
||||
UPROPERTY(Category = Node, VisibleInstanceOnly)
|
||||
uint32 bStopOnOverlap : 1;
|
||||
|
||||
UPROPERTY()
|
||||
uint32 bStopOnOverlapNeedsUpdate : 1;
|
||||
|
||||
/** if set, move will use pathfinding. Not exposed on purpose, please use BTTask_MoveDirectlyToward */
|
||||
uint32 bUsePathfinding : 1;
|
||||
|
||||
/** set automatically if move should use GameplayTasks */
|
||||
uint32 bUseGameplayTasks : 1;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) override;
|
||||
virtual void TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void PostLoad() override;
|
||||
|
||||
virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) override;
|
||||
virtual void OnMessage(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, FName Message, int32 RequestID, bool bSuccess) override;
|
||||
EBlackboardNotificationResult OnBlackboardValueChange(const UBlackboardComponent& Blackboard, FBlackboard::FKey ChangedKeyID);
|
||||
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
virtual void OnNodeCreated() override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
EBTNodeResult::Type PerformMoveTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);
|
||||
|
||||
/** prepares move task for activation */
|
||||
virtual UAITask_MoveTo* PrepareMoveTask(UBehaviorTreeComponent& OwnerComp, UAITask_MoveTo* ExistingTask, FAIMoveRequest& MoveRequest);
|
||||
};
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_PawnActionBase.generated.h"
|
||||
|
||||
class UPawnAction;
|
||||
|
||||
enum class EPawnActionTaskResult : uint8
|
||||
{
|
||||
Unknown,
|
||||
TaskFinished,
|
||||
TaskAborted,
|
||||
ActionLost,
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for managing pawn actions
|
||||
*
|
||||
* Task will set itself as action observer before pushing it to AI Controller,
|
||||
* override OnActionEvent if you need any special event handling.
|
||||
*
|
||||
* Please use result returned by PushAction for ExecuteTask function.
|
||||
*/
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UBTTask_PawnActionBase : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
protected:
|
||||
|
||||
/** starts executing pawn action */
|
||||
EBTNodeResult::Type PushAction(UBehaviorTreeComponent& OwnerComp, UPawnAction& Action);
|
||||
|
||||
/** action observer, updates state of task */
|
||||
virtual void OnActionEvent(UPawnAction& Action, EPawnActionEventType::Type Event);
|
||||
|
||||
/** called when action is removed from stack (FinishedAborting) by some external event
|
||||
* default behavior: finish task as failed */
|
||||
virtual void OnActionLost(UPawnAction& Action);
|
||||
|
||||
public:
|
||||
|
||||
/** helper functions, should be used when behavior tree task deals with pawn actions, but can't derive from this class */
|
||||
static EPawnActionTaskResult ActionEventHandler(UBTTaskNode* TaskNode, UPawnAction& Action, EPawnActionEventType::Type Event);
|
||||
};
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "TimerManager.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_PlayAnimation.generated.h"
|
||||
|
||||
/**
|
||||
* Play indicated AnimationAsset on Pawn controlled by BT
|
||||
* Note that this node is generic and is handing multiple special cases,
|
||||
* If you want a more efficient solution you'll need to implement it yourself (or wait for our BTTask_PlayCharacterAnimation)
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_PlayAnimation : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** Animation asset to play. Note that it needs to match the skeleton of pawn this BT is controlling */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
UAnimationAsset* AnimationToPlay;
|
||||
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
uint32 bLooping : 1;
|
||||
|
||||
/** if true the task will just trigger the animation and instantly finish. Fire and Forget. */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
uint32 bNonBlocking : 1;
|
||||
|
||||
UPROPERTY()
|
||||
UBehaviorTreeComponent* MyOwnerComp;
|
||||
|
||||
UPROPERTY()
|
||||
USkeletalMeshComponent* CachedSkelMesh;
|
||||
|
||||
EAnimationMode::Type PreviousAnimationMode;
|
||||
|
||||
FTimerDelegate TimerDelegate;
|
||||
FTimerHandle TimerHandle;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
void OnAnimationTimerDone();
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
void CleanUp(UBehaviorTreeComponent& OwnerComp);
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_PlaySound.generated.h"
|
||||
|
||||
class USoundCue;
|
||||
|
||||
/**
|
||||
* Play Sound task node.
|
||||
* Plays the specified sound when executed.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_PlaySound : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** CUE to play */
|
||||
UPROPERTY(Category=Node, EditAnywhere)
|
||||
USoundCue* SoundToPlay;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_PawnActionBase.h"
|
||||
#include "BTTask_PushPawnAction.generated.h"
|
||||
|
||||
class UPawnAction;
|
||||
|
||||
/**
|
||||
* Action task node.
|
||||
* Push pawn action to controller.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_PushPawnAction : public UBTTask_PawnActionBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, Instanced, Category = Action)
|
||||
UPawnAction* Action;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
};
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
|
||||
#include "BehaviorTree/Services/BTService_DefaultFocus.h"
|
||||
#include "BTTask_RotateToFaceBBEntry.generated.h"
|
||||
|
||||
class AAIController;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(config = Game)
|
||||
class AIMODULE_API UBTTask_RotateToFaceBBEntry : public UBTTask_BlackboardBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
/** Success condition precision in degrees */
|
||||
UPROPERTY(config, Category = Node, EditAnywhere, meta = (ClampMin = "0.0"))
|
||||
float Precision;
|
||||
|
||||
private:
|
||||
/** cached Precision tangent value */
|
||||
float PrecisionDot;
|
||||
|
||||
public:
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
virtual void PostLoad() override;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
virtual uint16 GetInstanceMemorySize() const override { return sizeof(FBTFocusMemory); }
|
||||
|
||||
protected:
|
||||
|
||||
float GetPrecisionDot() const { return PrecisionDot; }
|
||||
void CleanUp(AAIController& AIController, uint8* NodeMemory);
|
||||
};
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BehaviorTree/BehaviorTree.h"
|
||||
#include "BTTask_RunBehavior.generated.h"
|
||||
|
||||
/**
|
||||
* RunBehavior task allows pushing subtrees on execution stack.
|
||||
* Subtree asset can't be changed in runtime!
|
||||
*
|
||||
* This limitation is caused by support for subtree's root level decorators,
|
||||
* which are injected into parent tree, and structure of running tree
|
||||
* cannot be modified in runtime (see: BTNode: ExecutionIndex, MemoryOffset)
|
||||
*
|
||||
* Use RunBehaviorDynamic task for subtrees that need to be changed in runtime.
|
||||
*/
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_RunBehavior : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
/** @returns number of injected nodes */
|
||||
int32 GetInjectedNodesCount() const;
|
||||
|
||||
/** @returns subtree asset */
|
||||
UBehaviorTree* GetSubtreeAsset() const;
|
||||
|
||||
protected:
|
||||
|
||||
/** behavior to run */
|
||||
UPROPERTY(Category = Node, EditAnywhere)
|
||||
UBehaviorTree* BehaviorAsset;
|
||||
|
||||
/** called when subtree is removed from active stack */
|
||||
virtual void OnSubtreeDeactivated(UBehaviorTreeComponent& OwnerComp, EBTNodeResult::Type NodeResult);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE UBehaviorTree* UBTTask_RunBehavior::GetSubtreeAsset() const
|
||||
{
|
||||
return BehaviorAsset;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 UBTTask_RunBehavior::GetInjectedNodesCount() const
|
||||
{
|
||||
return BehaviorAsset ? BehaviorAsset->RootDecorators.Num() : 0;
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_RunBehaviorDynamic.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* RunBehaviorDynamic task allows pushing subtrees on execution stack.
|
||||
* Subtree asset can be assigned at runtime with SetDynamicSubtree function of BehaviorTreeComponent.
|
||||
*
|
||||
* Does NOT support subtree's root level decorators!
|
||||
*/
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_RunBehaviorDynamic : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual void OnInstanceCreated(UBehaviorTreeComponent& OwnerComp) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
bool HasMatchingTag(const FGameplayTag& Tag) const;
|
||||
bool SetBehaviorAsset(UBehaviorTree* NewBehaviorAsset);
|
||||
|
||||
protected:
|
||||
|
||||
/** Gameplay tag that will identify this task for subtree injection */
|
||||
UPROPERTY(Category=Node, EditAnywhere)
|
||||
FGameplayTag InjectionTag;
|
||||
|
||||
/** default behavior to run */
|
||||
UPROPERTY(Category=Node, EditAnywhere)
|
||||
UBehaviorTree* DefaultBehaviorAsset;
|
||||
|
||||
/** current subtree */
|
||||
UPROPERTY()
|
||||
UBehaviorTree* BehaviorAsset;
|
||||
|
||||
/** called when subtree is removed from active stack */
|
||||
virtual void OnSubtreeDeactivated(UBehaviorTreeComponent& OwnerComp, EBTNodeResult::Type NodeResult);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE bool UBTTask_RunBehaviorDynamic::HasMatchingTag(const FGameplayTag& Tag) const
|
||||
{
|
||||
return InjectionTag == Tag;
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_BlackboardBase.h"
|
||||
#include "BTTask_RunEQSQuery.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
class UEnvQuery;
|
||||
|
||||
struct FBTEnvQueryTaskMemory
|
||||
{
|
||||
/** Query request ID */
|
||||
int32 RequestID;
|
||||
};
|
||||
|
||||
/**
|
||||
* Run Environment Query System Query task node.
|
||||
* Runs the specified environment query when executed.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_RunEQSQuery : public UBTTask_BlackboardBase
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** query to run */
|
||||
UPROPERTY(Category = Node, VisibleAnywhere, meta = (EditCondition = "!bUseBBKey", DisplayName = "QueryTemplate_DEPRECATED"))
|
||||
UEnvQuery* QueryTemplate;
|
||||
|
||||
/** optional parameters for query */
|
||||
UPROPERTY(Category = Node, VisibleAnywhere, meta = (DisplayName = "QueryParams_DEPRECATED"))
|
||||
TArray<FEnvNamedValue> QueryParams;
|
||||
|
||||
UPROPERTY(Category = Node, VisibleAnywhere, meta = (DisplayName = "QueryConfig_DEPRECATED"))
|
||||
TArray<FAIDynamicParam> QueryConfig;
|
||||
|
||||
/** determines which item will be stored (All = only first matching) */
|
||||
UPROPERTY(Category = Node, VisibleAnywhere, meta = (DisplayName = "RunMode_DEPRECATED"))
|
||||
TEnumAsByte<EEnvQueryRunMode::Type> RunMode;
|
||||
|
||||
/** blackboard key storing an EQS query template */
|
||||
UPROPERTY(VisibleAnywhere, Category = Blackboard, meta = (EditCondition = "bUseBBKey", DisplayName = "EQSQueryBlackboardKey_DEPRECATED"))
|
||||
struct FBlackboardKeySelector EQSQueryBlackboardKey;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category=Node, meta=(InlineEditConditionToggle))
|
||||
bool bUseBBKey;
|
||||
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
FEQSParametrizedQueryExecutionRequest EQSRequest;
|
||||
|
||||
FQueryFinishedSignature QueryFinishedDelegate;
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
|
||||
/** finish task */
|
||||
void OnQueryFinished(TSharedPtr<FEnvQueryResult> Result);
|
||||
|
||||
/** Convert QueryParams to QueryConfig */
|
||||
virtual void PostLoad() override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** prepare query params */
|
||||
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
/** gather all filters from existing EnvQueryItemTypes */
|
||||
void CollectKeyFilters();
|
||||
};
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_SetTagCooldown.generated.h"
|
||||
|
||||
/**
|
||||
* Cooldown task node.
|
||||
* Sets a cooldown tag value. Use with cooldown tag decorators to prevent behavior tree execution.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_SetTagCooldown : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** Gameplay tag that will be used for the cooldown. */
|
||||
UPROPERTY(Category = Cooldown, EditAnywhere)
|
||||
FGameplayTag CooldownTag;
|
||||
|
||||
/** True if we are adding to any existing duration, false if we are setting the duration (potentially invalidating an existing end time). */
|
||||
UPROPERTY(Category = Decorator, EditAnywhere)
|
||||
bool bAddToExistingDuration;
|
||||
|
||||
/** Value we will add or set to the Cooldown tag when this task runs. */
|
||||
UPROPERTY(Category = Cooldown, EditAnywhere)
|
||||
float CooldownDuration;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/BTTaskNode.h"
|
||||
#include "BTTask_Wait.generated.h"
|
||||
|
||||
struct FBTWaitTaskMemory
|
||||
{
|
||||
/** time left */
|
||||
float RemainingWaitTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait task node.
|
||||
* Wait for the specified time when executed.
|
||||
*/
|
||||
UCLASS()
|
||||
class AIMODULE_API UBTTask_Wait : public UBTTaskNode
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
/** wait time in seconds */
|
||||
UPROPERTY(Category = Wait, EditAnywhere, meta = (ClampMin = "0.0", UIMin = "0.0"))
|
||||
float WaitTime;
|
||||
|
||||
/** allows adding random time to wait time */
|
||||
UPROPERTY(Category = Wait, EditAnywhere, meta = (UIMin = 0, ClampMin = 0))
|
||||
float RandomDeviation;
|
||||
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual uint16 GetInstanceMemorySize() const override;
|
||||
virtual void DescribeRuntimeValues(const UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTDescriptionVerbosity::Type Verbosity, TArray<FString>& Values) const override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FName GetNodeIconName() const override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
protected:
|
||||
|
||||
virtual void TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;
|
||||
};
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "BehaviorTree/Tasks/BTTask_Wait.h"
|
||||
#include "BTTask_WaitBlackboardTime.generated.h"
|
||||
|
||||
class UBehaviorTree;
|
||||
|
||||
/**
|
||||
* Wait task node.
|
||||
* Wait for the time specified by a Blackboard key when executed.
|
||||
*/
|
||||
UCLASS(hidecategories=Wait)
|
||||
class AIMODULE_API UBTTask_WaitBlackboardTime : public UBTTask_Wait
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void InitializeFromAsset(UBehaviorTree& Asset) override;
|
||||
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
|
||||
virtual FString GetStaticDescription() const override;
|
||||
|
||||
/** get name of selected blackboard key */
|
||||
FName GetSelectedBlackboardKey() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** blackboard key selector */
|
||||
UPROPERTY(EditAnywhere, Category=Blackboard)
|
||||
struct FBlackboardKeySelector BlackboardKey;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE FName UBTTask_WaitBlackboardTime::GetSelectedBlackboardKey() const
|
||||
{
|
||||
return BlackboardKey.SelectedKeyName;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "AITypes.h"
|
||||
#include "Navigation/PathFollowingComponent.h"
|
||||
#include "AIAsyncTaskBlueprintProxy.generated.h"
|
||||
|
||||
class AAIController;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOAISimpleDelegate, EPathFollowingResult::Type, MovementResult);
|
||||
|
||||
UCLASS(MinimalAPI)
|
||||
class UAIAsyncTaskBlueprintProxy : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOAISimpleDelegate OnSuccess;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOAISimpleDelegate OnFail;
|
||||
|
||||
public:
|
||||
UFUNCTION()
|
||||
void OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type MovementResult);
|
||||
|
||||
void OnNoPath();
|
||||
void OnAtGoal();
|
||||
|
||||
//~ Begin UObject Interface
|
||||
virtual void BeginDestroy() override;
|
||||
//~ End UObject Interface
|
||||
|
||||
TWeakObjectPtr<AAIController> AIController;
|
||||
FAIRequestID MoveRequestId;
|
||||
TWeakObjectPtr<UWorld> MyWorld;
|
||||
|
||||
FTimerHandle TimerHandle_OnInstantFinish;
|
||||
};
|
||||
@@ -1,99 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
/**
|
||||
* This kismet library is used for helper functions primarily used in the kismet compiler for AI related nodes
|
||||
* NOTE: Do not change the signatures for any of these functions as it can break the kismet compiler and/or the nodes referencing them
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "AIBlueprintHelperLibrary.generated.h"
|
||||
|
||||
class AAIController;
|
||||
class UAIAsyncTaskBlueprintProxy;
|
||||
class UAnimInstance;
|
||||
class UBehaviorTree;
|
||||
class UBlackboardComponent;
|
||||
class UNavigationPath;
|
||||
class UPathFollowingComponent;
|
||||
|
||||
UCLASS(meta=(ScriptName="AIHelperLibrary"))
|
||||
class AIMODULE_API UAIBlueprintHelperLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta=(WorldContext="WorldContextObject", BlueprintInternalUseOnly = "TRUE"))
|
||||
static UAIAsyncTaskBlueprintProxy* CreateMoveToProxyObject(UObject* WorldContextObject, APawn* Pawn, FVector Destination, AActor* TargetActor = NULL, float AcceptanceRadius = 5.f, bool bStopOnOverlap = false);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AI", meta=(DefaultToSelf="MessageSource"))
|
||||
static void SendAIMessage(APawn* Target, FName Message, UObject* MessageSource, bool bSuccess = true);
|
||||
|
||||
/** Spawns AI agent of a given class. The PawnClass needs to have AIController
|
||||
* set for the function to spawn a controller as well.
|
||||
* @param BehaviorTree if set, and the function has successfully spawned
|
||||
* and AI controller, this BehaviorTree asset will be assigned to the AI
|
||||
* controller, and run.
|
||||
* @param Owner lets you spawn the AI in a sublevel rather than in the
|
||||
* persistent level (which is the default behavior).
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="AI", meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction="true", AdvancedDisplay = "Owner"))
|
||||
static APawn* SpawnAIFromClass(UObject* WorldContextObject, TSubclassOf<APawn> PawnClass, UBehaviorTree* BehaviorTree, FVector Location, FRotator Rotation = FRotator::ZeroRotator, bool bNoCollisionFail = false, AActor* Owner = nullptr);
|
||||
|
||||
/** The way it works exactly is if the actor passed in is a pawn, then the function retrieves
|
||||
* pawn's controller cast to AIController. Otherwise the function returns actor cast to AIController. */
|
||||
UFUNCTION(BlueprintPure, Category = "AI", meta = (DefaultToSelf = "ControlledObject"))
|
||||
static AAIController* GetAIController(AActor* ControlledActor);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category="AI", meta=(DefaultToSelf="Target"))
|
||||
static UBlackboardComponent* GetBlackboard(AActor* Target);
|
||||
|
||||
/** locks indicated AI resources of animated pawn */
|
||||
UFUNCTION(BlueprintCallable, Category = "Animation", BlueprintAuthorityOnly, meta = (DefaultToSelf = "AnimInstance"))
|
||||
static void LockAIResourcesWithAnimation(UAnimInstance* AnimInstance, bool bLockMovement, bool LockAILogic);
|
||||
|
||||
/** unlocks indicated AI resources of animated pawn. Will unlock only animation-locked resources */
|
||||
UFUNCTION(BlueprintCallable, Category = "Animation", BlueprintAuthorityOnly, meta = (DefaultToSelf = "AnimInstance"))
|
||||
static void UnlockAIResourcesWithAnimation(UAnimInstance* AnimInstance, bool bUnlockMovement, bool UnlockAILogic);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI")
|
||||
static bool IsValidAILocation(FVector Location);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI")
|
||||
static bool IsValidAIDirection(FVector DirectionVector);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI")
|
||||
static bool IsValidAIRotation(FRotator Rotation);
|
||||
|
||||
/** Returns a NEW UOBJECT that is a COPY of navigation path given controller is currently using.
|
||||
* The result being a copy means you won't be able to influence agent's pathfollowing
|
||||
* by manipulating received path.
|
||||
* Please use GetCurrentPathPoints if you only need the array of path points. */
|
||||
UFUNCTION(BlueprintPure, Category = "AI", meta = (UnsafeDuringActorConstruction = "true"))
|
||||
static UNavigationPath* GetCurrentPath(AController* Controller);
|
||||
|
||||
/** Returns an array of navigation path points given controller is currently using. */
|
||||
UFUNCTION(BlueprintPure, Category = "AI", meta = (UnsafeDuringActorConstruction = "true"))
|
||||
static const TArray<FVector> GetCurrentPathPoints(AController* Controller);
|
||||
|
||||
/** Return the path index the given controller is currently at. Returns INDEX_NONE if no path. */
|
||||
UFUNCTION(BlueprintPure, Category = "AI", meta = (UnsafeDuringActorConstruction = "true"))
|
||||
static int32 GetCurrentPathIndex(const AController* Controller);
|
||||
|
||||
/** Return the path index of the next nav link for the current path of the given controller. Returns INDEX_NONE if no path or no incoming nav link. */
|
||||
UFUNCTION(BlueprintPure, Category = "AI", meta = (UnsafeDuringActorConstruction = "true"))
|
||||
static int32 GetNextNavLinkIndex(const AController* Controller);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
static void SimpleMoveToActor(AController* Controller, const AActor* Goal);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Navigation")
|
||||
static void SimpleMoveToLocation(AController* Controller, const FVector& Goal);
|
||||
|
||||
private:
|
||||
static UPathFollowingComponent* GetPathComp(const AController* Controller);
|
||||
};
|
||||
@@ -1,235 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/WeakObjectPtr.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "AITypes.h"
|
||||
#include "AIResourceInterface.h"
|
||||
#include "BrainComponent.generated.h"
|
||||
|
||||
class AAIController;
|
||||
class AController;
|
||||
class APawn;
|
||||
class UBlackboardComponent;
|
||||
class UBrainComponent;
|
||||
struct FAIMessage;
|
||||
struct FAIMessageObserver;
|
||||
|
||||
DECLARE_DELEGATE_TwoParams(FOnAIMessage, UBrainComponent*, const FAIMessage&);
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogBrain, Warning, All);
|
||||
|
||||
struct AIMODULE_API FAIMessage
|
||||
{
|
||||
enum EStatus
|
||||
{
|
||||
Failure,
|
||||
Success,
|
||||
};
|
||||
|
||||
/** type of message */
|
||||
FName MessageName;
|
||||
|
||||
/** message source */
|
||||
FWeakObjectPtr Sender;
|
||||
|
||||
/** message param: ID */
|
||||
FAIRequestID RequestID;
|
||||
|
||||
/** message param: status */
|
||||
TEnumAsByte<EStatus> Status;
|
||||
|
||||
/** message param: custom flags */
|
||||
uint8 MessageFlags;
|
||||
|
||||
FAIMessage() : MessageName(NAME_None), Sender(NULL), RequestID(0), Status(FAIMessage::Success), MessageFlags(0) {}
|
||||
FAIMessage(FName InMessage, UObject* InSender) : MessageName(InMessage), Sender(InSender), RequestID(0), Status(FAIMessage::Success), MessageFlags(0) {}
|
||||
FAIMessage(FName InMessage, UObject* InSender, FAIRequestID InID, EStatus InStatus) : MessageName(InMessage), Sender(InSender), RequestID(InID), Status(InStatus), MessageFlags(0) {}
|
||||
FAIMessage(FName InMessage, UObject* InSender, FAIRequestID InID, bool bSuccess) : MessageName(InMessage), Sender(InSender), RequestID(InID), Status(bSuccess ? Success : Failure), MessageFlags(0) {}
|
||||
FAIMessage(FName InMessage, UObject* InSender, EStatus InStatus) : MessageName(InMessage), Sender(InSender), RequestID(0), Status(InStatus), MessageFlags(0) {}
|
||||
FAIMessage(FName InMessage, UObject* InSender, bool bSuccess) : MessageName(InMessage), Sender(InSender), RequestID(0), Status(bSuccess ? Success : Failure), MessageFlags(0) {}
|
||||
|
||||
void SetFlags(uint8 Flags) { MessageFlags = Flags; }
|
||||
void SetFlag(uint8 Flag) { MessageFlags |= Flag; }
|
||||
void ClearFlag(uint8 Flag) { MessageFlags &= ~Flag; }
|
||||
bool HasFlag(uint8 Flag) const { return (MessageFlags & Flag) != 0; }
|
||||
|
||||
static void Send(AController* Controller, const FAIMessage& Message);
|
||||
static void Send(APawn* Pawn, const FAIMessage& Message);
|
||||
static void Send(UBrainComponent* BrainComp, const FAIMessage& Message);
|
||||
|
||||
static void Broadcast(UObject* WorldContextObject, const FAIMessage& Message);
|
||||
};
|
||||
|
||||
typedef TSharedPtr<struct FAIMessageObserver, ESPMode::Fast> FAIMessageObserverHandle;
|
||||
|
||||
struct AIMODULE_API FAIMessageObserver : public TSharedFromThis<FAIMessageObserver>
|
||||
{
|
||||
public:
|
||||
FAIMessageObserver();
|
||||
|
||||
static FAIMessageObserverHandle Create(AController* Controller, FName MessageType, FOnAIMessage const& Delegate);
|
||||
static FAIMessageObserverHandle Create(AController* Controller, FName MessageType, FAIRequestID MessageID, FOnAIMessage const& Delegate);
|
||||
|
||||
static FAIMessageObserverHandle Create(APawn* Pawn, FName MessageType, FOnAIMessage const& Delegate);
|
||||
static FAIMessageObserverHandle Create(APawn* Pawn, FName MessageType, FAIRequestID MessageID, FOnAIMessage const& Delegate);
|
||||
|
||||
static FAIMessageObserverHandle Create(UBrainComponent* BrainComp, FName MessageType, FOnAIMessage const& Delegate);
|
||||
static FAIMessageObserverHandle Create(UBrainComponent* BrainComp, FName MessageType, FAIRequestID MessageID, FOnAIMessage const& Delegate);
|
||||
|
||||
~FAIMessageObserver();
|
||||
|
||||
void OnMessage(const FAIMessage& Message);
|
||||
FString DescribeObservedMessage() const;
|
||||
|
||||
FORCEINLINE FName GetObservedMessageType() const { return MessageType; }
|
||||
FORCEINLINE FAIRequestID GetObservedMessageID() const { return MessageID; }
|
||||
FORCEINLINE bool IsObservingMessageID() const { return bFilterByID; }
|
||||
|
||||
private:
|
||||
|
||||
void Register(UBrainComponent* OwnerComp);
|
||||
void Unregister();
|
||||
|
||||
/** observed message type */
|
||||
FName MessageType;
|
||||
|
||||
/** filter: message ID */
|
||||
FAIRequestID MessageID;
|
||||
bool bFilterByID;
|
||||
|
||||
/** delegate to call */
|
||||
FOnAIMessage ObserverDelegate;
|
||||
|
||||
/** brain component owning this observer */
|
||||
TWeakObjectPtr<UBrainComponent> Owner;
|
||||
|
||||
// Non-copyable
|
||||
FAIMessageObserver(const FAIMessageObserver&);
|
||||
FAIMessageObserver& operator=(const FAIMessageObserver&);
|
||||
};
|
||||
|
||||
UCLASS(ClassGroup = AI, BlueprintType, hidecategories = (Sockets, Collision))
|
||||
class AIMODULE_API UBrainComponent : public UActorComponent, public IAIResourceInterface
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
protected:
|
||||
/** blackboard component */
|
||||
UPROPERTY(transient)
|
||||
UBlackboardComponent* BlackboardComp;
|
||||
|
||||
UPROPERTY(transient)
|
||||
AAIController* AIOwner;
|
||||
|
||||
// @TODO this is a temp contraption to implement delayed messages delivering
|
||||
// until proper AI messaging is implemented
|
||||
TArray<FAIMessage> MessagesToProcess;
|
||||
|
||||
public:
|
||||
virtual FString GetDebugInfoString() const { return TEXT(""); }
|
||||
|
||||
/** To be called in case we want to restart AI logic while it's still being locked.
|
||||
* On subsequent ResumeLogic instead RestartLogic will be called.
|
||||
* @note this call does nothing if logic is not locked at the moment of call */
|
||||
void RequestLogicRestartOnUnlock();
|
||||
|
||||
/** Starts brain logic. If brain is already running, will not do anything. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Logic")
|
||||
virtual void StartLogic();
|
||||
|
||||
/** Restarts currently running or previously ran brain logic. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Logic")
|
||||
virtual void RestartLogic();
|
||||
|
||||
/** Stops currently running brain logic. */
|
||||
UFUNCTION(BlueprintCallable, Category = "AI|Logic")
|
||||
virtual void StopLogic(const FString& Reason);
|
||||
|
||||
/** AI logic won't be needed anymore, stop all activity and run cleanup */
|
||||
virtual void Cleanup() {}
|
||||
|
||||
/** Pause logic and blackboard updates. */
|
||||
virtual void PauseLogic(const FString& Reason) {}
|
||||
|
||||
/** Resumes paused brain logic.
|
||||
* MUST be called by child implementations!
|
||||
* @return indicates whether child class' ResumeLogic should be called (true) or has it been
|
||||
* handled in a different way and no other actions are required (false)*/
|
||||
virtual EAILogicResuming::Type ResumeLogic(const FString& Reason);
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI|Logic")
|
||||
virtual bool IsRunning() const;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AI|Logic")
|
||||
virtual bool IsPaused() const;
|
||||
|
||||
#if ENABLE_VISUAL_LOG
|
||||
virtual void DescribeSelfToVisLog(struct FVisualLogEntry* Snapshot) const;
|
||||
#endif // ENABLE_VISUAL_LOG
|
||||
|
||||
// IAIResourceInterface begin
|
||||
virtual void LockResource(EAIRequestPriority::Type LockSource) override;
|
||||
virtual void ClearResourceLock(EAIRequestPriority::Type LockSource) override;
|
||||
virtual void ForceUnlockResource() override;
|
||||
virtual bool IsResourceLocked() const override;
|
||||
// IAIResourceInterface end
|
||||
|
||||
virtual void HandleMessage(const FAIMessage& Message);
|
||||
|
||||
/** BEGIN UActorComponent overrides */
|
||||
virtual void InitializeComponent() override;
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
virtual void OnRegister() override;
|
||||
/** END UActorComponent overrides */
|
||||
|
||||
/** caches BlackboardComponent's pointer to be used with this brain component */
|
||||
void CacheBlackboardComponent(UBlackboardComponent* BBComp);
|
||||
|
||||
/** @return blackboard used with this component */
|
||||
UBlackboardComponent* GetBlackboardComponent();
|
||||
|
||||
/** @return blackboard used with this component */
|
||||
const UBlackboardComponent* GetBlackboardComponent() const;
|
||||
|
||||
FORCEINLINE AAIController* GetAIOwner() const { return AIOwner; }
|
||||
|
||||
protected:
|
||||
|
||||
/** active message observers */
|
||||
TArray<FAIMessageObserver*> MessageObservers;
|
||||
|
||||
friend struct FAIMessageObserver;
|
||||
friend struct FAIMessage;
|
||||
|
||||
/** used to keep track of which subsystem requested this AI resource be locked */
|
||||
FAIResourceLock ResourceLock;
|
||||
|
||||
private:
|
||||
uint32 bDoLogicRestartOnUnlock : 1;
|
||||
|
||||
public:
|
||||
// static names to be used with SendMessage. Fell free to define game-specific
|
||||
// messages anywhere you want
|
||||
static const FName AIMessage_MoveFinished;
|
||||
static const FName AIMessage_RepathFailed;
|
||||
static const FName AIMessage_QueryFinished;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inlines
|
||||
|
||||
FORCEINLINE UBlackboardComponent* UBrainComponent::GetBlackboardComponent()
|
||||
{
|
||||
return BlackboardComp;
|
||||
}
|
||||
|
||||
FORCEINLINE const UBlackboardComponent* UBrainComponent::GetBlackboardComponent() const
|
||||
{
|
||||
return BlackboardComp;
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Templates/SubclassOf.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
#include "AIDataProvider.generated.h"
|
||||
|
||||
class UAIDataProvider;
|
||||
|
||||
/**
|
||||
* AIDataProvider is an object that can provide collection of properties
|
||||
* associated with bound pawn owner or request Id.
|
||||
*
|
||||
* Editable properties are used to set up provider instance,
|
||||
* creating additional filters or ways of accessing data (e.g. gameplay tag of ability)
|
||||
*
|
||||
* Non editable properties are holding data
|
||||
*/
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
private:
|
||||
/** cached uproperty of provider */
|
||||
mutable FProperty* CachedProperty;
|
||||
|
||||
public:
|
||||
/** (optional) provider for dynamic data binding */
|
||||
UPROPERTY(EditAnywhere, Instanced, Category = Value)
|
||||
UAIDataProvider* DataBinding;
|
||||
|
||||
/** name of provider's value property */
|
||||
UPROPERTY(EditAnywhere, Category = Value)
|
||||
FName DataField;
|
||||
|
||||
/** describe default data */
|
||||
virtual FString ValueToString() const;
|
||||
FString ToString() const;
|
||||
|
||||
/** filter for provider's properties */
|
||||
virtual bool IsMatchingType(FProperty* PropType) const;
|
||||
|
||||
/** find all properties of provider that are matching filter */
|
||||
void GetMatchingProperties(TArray<FName>& MatchingProperties) const;
|
||||
|
||||
/** return raw data from provider's property */
|
||||
template<typename T>
|
||||
T* GetRawValuePtr() const
|
||||
{
|
||||
return CachedProperty ? CachedProperty->ContainerPtrToValuePtr<T>(DataBinding) : nullptr;
|
||||
}
|
||||
|
||||
/** bind data in provider and cache property for faster access */
|
||||
void BindData(const UObject* Owner, int32 RequestId) const;
|
||||
|
||||
FORCEINLINE bool IsDynamic() const { return DataBinding != nullptr; }
|
||||
|
||||
FAIDataProviderValue() :
|
||||
CachedProperty(nullptr),
|
||||
DataBinding(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~FAIDataProviderValue() {};
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderTypedValue : public FAIDataProviderValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FAIDataProviderTypedValue()
|
||||
: PropertyType_DEPRECATED(nullptr)
|
||||
, PropertyType(nullptr)
|
||||
{}
|
||||
|
||||
/** type of value */
|
||||
UPROPERTY()
|
||||
UClass* PropertyType_DEPRECATED;
|
||||
FFieldClass* PropertyType;
|
||||
|
||||
/** filter for provider's properties */
|
||||
virtual bool IsMatchingType(FProperty* PropType) const override;
|
||||
|
||||
/** Implementing Serialize to convert UClass to FFieldClass */
|
||||
bool Serialize(FArchive& Ar);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TStructOpsTypeTraits<FAIDataProviderTypedValue> : public TStructOpsTypeTraitsBase2<FAIDataProviderTypedValue>
|
||||
{
|
||||
enum
|
||||
{
|
||||
WithSerializer = true,
|
||||
};
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderStructValue : public FAIDataProviderValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
/** name of UStruct type */
|
||||
FString StructName;
|
||||
|
||||
virtual bool IsMatchingType(FProperty* PropType) const override;
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderIntValue : public FAIDataProviderTypedValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
FAIDataProviderIntValue();
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Value)
|
||||
int32 DefaultValue;
|
||||
|
||||
int32 GetValue() const;
|
||||
virtual FString ValueToString() const override;
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderFloatValue : public FAIDataProviderTypedValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
FAIDataProviderFloatValue();
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Value)
|
||||
float DefaultValue;
|
||||
|
||||
float GetValue() const;
|
||||
virtual FString ValueToString() const override;
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct AIMODULE_API FAIDataProviderBoolValue : public FAIDataProviderTypedValue
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
FAIDataProviderBoolValue();
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = Value)
|
||||
bool DefaultValue;
|
||||
|
||||
bool GetValue() const;
|
||||
virtual FString ValueToString() const override;
|
||||
};
|
||||
|
||||
UCLASS(EditInlineNew, Abstract, CollapseCategories, AutoExpandCategories=(Provider))
|
||||
class AIMODULE_API UAIDataProvider : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void BindData(const UObject& Owner, int32 RequestId);
|
||||
virtual FString ToString(FName PropName) const;
|
||||
};
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "DataProviders/AIDataProvider.h"
|
||||
#include "AIDataProvider_QueryParams.generated.h"
|
||||
|
||||
/**
|
||||
* AIDataProvider_QueryParams is used with environment queries
|
||||
*
|
||||
* It allows defining simple parameters for running query,
|
||||
* which are not tied to any specific pawn, but defined
|
||||
* for every query execution.
|
||||
*/
|
||||
|
||||
UCLASS(EditInlineNew, meta=(DisplayName="Query Params"))
|
||||
class AIMODULE_API UAIDataProvider_QueryParams : public UAIDataProvider
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void BindData(const UObject& Owner, int32 RequestId) override;
|
||||
virtual FString ToString(FName PropName) const override;
|
||||
|
||||
/** Arbitrary name this query parameter will be exposed as to outside world (like BT nodes) */
|
||||
UPROPERTY(EditAnywhere, Category = Provider)
|
||||
FName ParamName;
|
||||
|
||||
UPROPERTY()
|
||||
float FloatValue;
|
||||
|
||||
UPROPERTY()
|
||||
int32 IntValue;
|
||||
|
||||
UPROPERTY()
|
||||
bool BoolValue;
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DataProviders/AIDataProvider_QueryParams.h"
|
||||
#include "AIDataProvider_Random.generated.h"
|
||||
|
||||
UCLASS(EditInlineNew, meta = (DisplayName = "Random number"))
|
||||
class UAIDataProvider_Random : public UAIDataProvider_QueryParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, Category = AI)
|
||||
float Min;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = AI)
|
||||
float Max;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = AI)
|
||||
uint8 bInteger : 1;
|
||||
|
||||
public:
|
||||
UAIDataProvider_Random(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
virtual void BindData(const UObject& Owner, int32 RequestId) override;
|
||||
virtual FString ToString(FName PropName) const override;
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "AIController.h"
|
||||
#include "DetourCrowdAIController.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class ADetourCrowdAIController : public AAIController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
ADetourCrowdAIController(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
};
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryContext.h"
|
||||
#include "EnvQueryContext_BlueprintBase.generated.h"
|
||||
|
||||
class AActor;
|
||||
struct FEnvQueryContextData;
|
||||
struct FEnvQueryInstance;
|
||||
|
||||
UCLASS(MinimalAPI, Abstract, Blueprintable)
|
||||
class UEnvQueryContext_BlueprintBase : public UEnvQueryContext
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
enum ECallMode
|
||||
{
|
||||
InvalidCallMode,
|
||||
SingleActor,
|
||||
SingleLocation,
|
||||
ActorSet,
|
||||
LocationSet
|
||||
};
|
||||
|
||||
ECallMode CallMode;
|
||||
|
||||
// We need to implement GetWorld() so that blueprint functions which use a hidden WorldContextObject* will work properly.
|
||||
virtual UWorld* GetWorld() const override;
|
||||
|
||||
virtual void ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ProvideSingleActor(UObject* QuerierObject, AActor* QuerierActor, AActor*& ResultingActor) const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ProvideSingleLocation(UObject* QuerierObject, AActor* QuerierActor, FVector& ResultingLocation) const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ProvideActorsSet(UObject* QuerierObject, AActor* QuerierActor, TArray<AActor*>& ResultingActorsSet) const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void ProvideLocationsSet(UObject* QuerierObject, AActor* QuerierActor, TArray<FVector>& ResultingLocationSet) const;
|
||||
};
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryContext.h"
|
||||
#include "EnvQueryContext_Item.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class AIMODULE_API UEnvQueryContext_Item : public UEnvQueryContext
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
};
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryContext.h"
|
||||
#include "EnvQueryContext_Querier.generated.h"
|
||||
|
||||
struct FEnvQueryContextData;
|
||||
struct FEnvQueryInstance;
|
||||
|
||||
UCLASS(MinimalAPI)
|
||||
class UEnvQueryContext_Querier : public UEnvQueryContext
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override;
|
||||
};
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "EQSQueryResultSourceInterface.generated.h"
|
||||
|
||||
UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
|
||||
class UEQSQueryResultSourceInterface : public UInterface
|
||||
{
|
||||
GENERATED_UINTERFACE_BODY()
|
||||
};
|
||||
|
||||
class IEQSQueryResultSourceInterface
|
||||
{
|
||||
GENERATED_IINTERFACE_BODY()
|
||||
|
||||
virtual const struct FEnvQueryResult* GetQueryResult() const { return NULL; }
|
||||
virtual const struct FEnvQueryInstance* GetQueryInstance() const { return NULL; }
|
||||
|
||||
// debugging
|
||||
virtual bool GetShouldDebugDrawLabels() const { return true; }
|
||||
virtual bool GetShouldDrawFailedItems() const { return true; }
|
||||
virtual float GetHighlightRangePct() const { return 1.0f; }
|
||||
};
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "PrimitiveViewRelevance.h"
|
||||
#include "DebugRenderSceneProxy.h"
|
||||
#include "EnvironmentQuery/EnvQueryDebugHelpers.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "EQSRenderingComponent.generated.h"
|
||||
|
||||
class APlayerController;
|
||||
class IEQSQueryResultSourceInterface;
|
||||
class UCanvas;
|
||||
|
||||
class AIMODULE_API FEQSSceneProxy final : public FDebugRenderSceneProxy
|
||||
{
|
||||
friend class FEQSRenderingDebugDrawDelegateHelper;
|
||||
public:
|
||||
SIZE_T GetTypeHash() const override;
|
||||
|
||||
explicit FEQSSceneProxy(const UPrimitiveComponent& InComponent, const FString& ViewFlagName = TEXT("DebugAI"), const TArray<FSphere>& Spheres = TArray<FSphere>(), const TArray<FText3d>& Texts = TArray<FText3d>());
|
||||
|
||||
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override;
|
||||
|
||||
#if USE_EQS_DEBUGGER
|
||||
static void CollectEQSData(const UPrimitiveComponent* InComponent, const IEQSQueryResultSourceInterface* QueryDataSource, TArray<FSphere>& Spheres, TArray<FText3d>& Texts, TArray<EQSDebug::FDebugHelper>& DebugItems);
|
||||
static void CollectEQSData(const FEnvQueryResult* ResultItems, const FEnvQueryInstance* QueryInstance, float HighlightRangePct, bool ShouldDrawFailedItems, TArray<FSphere>& Spheres, TArray<FText3d>& Texts, TArray<EQSDebug::FDebugHelper>& DebugItems);
|
||||
#endif
|
||||
private:
|
||||
FEnvQueryResult QueryResult;
|
||||
// can be 0
|
||||
AActor* ActorOwner;
|
||||
const IEQSQueryResultSourceInterface* QueryDataSource;
|
||||
uint32 bDrawOnlyWhenSelected : 1;
|
||||
|
||||
static const FVector ItemDrawRadius;
|
||||
|
||||
bool SafeIsActorSelected() const;
|
||||
};
|
||||
|
||||
#if USE_EQS_DEBUGGER
|
||||
class FEQSRenderingDebugDrawDelegateHelper : public FDebugDrawDelegateHelper
|
||||
{
|
||||
typedef FDebugDrawDelegateHelper Super;
|
||||
|
||||
public:
|
||||
FEQSRenderingDebugDrawDelegateHelper()
|
||||
: ActorOwner(NULL)
|
||||
, QueryDataSource(NULL)
|
||||
, bDrawOnlyWhenSelected(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void InitDelegateHelper(const FDebugRenderSceneProxy* InSceneProxy) override
|
||||
{
|
||||
check(0);
|
||||
}
|
||||
|
||||
void InitDelegateHelper(const FEQSSceneProxy* InSceneProxy)
|
||||
{
|
||||
Super::InitDelegateHelper(InSceneProxy);
|
||||
|
||||
ActorOwner = InSceneProxy->ActorOwner;
|
||||
QueryDataSource = InSceneProxy->QueryDataSource;
|
||||
bDrawOnlyWhenSelected = InSceneProxy->bDrawOnlyWhenSelected;
|
||||
}
|
||||
|
||||
protected:
|
||||
AIMODULE_API virtual void DrawDebugLabels(UCanvas* Canvas, APlayerController*) override;
|
||||
|
||||
private:
|
||||
// can be 0
|
||||
AActor* ActorOwner;
|
||||
const IEQSQueryResultSourceInterface* QueryDataSource;
|
||||
uint32 bDrawOnlyWhenSelected : 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
UCLASS(hidecategories=Object)
|
||||
class AIMODULE_API UEQSRenderingComponent : public UPrimitiveComponent
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
FString DrawFlagName;
|
||||
uint32 bDrawOnlyWhenSelected : 1;
|
||||
|
||||
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
|
||||
virtual FBoxSphereBounds CalcBounds(const FTransform &LocalToWorld) const override;
|
||||
virtual void CreateRenderState_Concurrent(FRegisterComponentContext* Context) override;
|
||||
virtual void DestroyRenderState_Concurrent() override;
|
||||
|
||||
void ClearStoredDebugData();
|
||||
#if USE_EQS_DEBUGGER || ENABLE_VISUAL_LOG
|
||||
void StoreDebugData(const EQSDebug::FQueryData& DebugData);
|
||||
#endif
|
||||
#if USE_EQS_DEBUGGER
|
||||
FEQSRenderingDebugDrawDelegateHelper EQSRenderingDebugDrawDelegateHelper;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
//EQSDebug::FQueryData DebugData;
|
||||
TArray<FDebugRenderSceneProxy::FSphere> DebugDataSolidSpheres;
|
||||
TArray<FDebugRenderSceneProxy::FText3d> DebugDataTexts;
|
||||
};
|
||||
@@ -1,123 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "EnvironmentQuery/EQSQueryResultSourceInterface.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "EQSTestingPawn.generated.h"
|
||||
|
||||
class UEnvQuery;
|
||||
class UEQSRenderingComponent;
|
||||
|
||||
UENUM()
|
||||
enum class EEnvQueryHightlightMode : uint8
|
||||
{
|
||||
All,
|
||||
Best5Pct UMETA(DisplayName = "Best 5%"),
|
||||
Best25Pct UMETA(DisplayName = "Best 25%"),
|
||||
};
|
||||
|
||||
/** this class is abstract even though it's perfectly functional on its own.
|
||||
* The reason is to stop it from showing as valid player pawn type when configuring
|
||||
* project's game mode. */
|
||||
UCLASS(abstract, hidecategories=(Advanced, Attachment, Mesh, Animation, Clothing, Physics, Rendering, Lighting, Activation, CharacterMovement, AgentPhysics, Avoidance, MovementComponent, Velocity, Shape, Camera, Input, Layers, SkeletalMesh, Optimization, Pawn, Replication, Actor))
|
||||
class AIMODULE_API AEQSTestingPawn : public ACharacter, public IEQSQueryResultSourceInterface
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
UEnvQuery* QueryTemplate;
|
||||
|
||||
/** optional parameters for query */
|
||||
UPROPERTY(Category=EQS, VisibleAnywhere, meta=(DisplayName="QueryParams_DEPRECATED"))
|
||||
TArray<FEnvNamedValue> QueryParams;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
TArray<FAIDynamicParam> QueryConfig;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
float TimeLimitPerStep;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
int32 StepToDebugDraw;
|
||||
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
EEnvQueryHightlightMode HighlightMode;
|
||||
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
uint32 bDrawLabels:1;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
uint32 bDrawFailedItems:1;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
uint32 bReRunQueryOnlyOnFinishedMove:1;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
uint32 bShouldBeVisibleInGame:1;
|
||||
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
uint32 bTickDuringGame : 1;
|
||||
|
||||
UPROPERTY(Category=EQS, EditAnywhere)
|
||||
TEnumAsByte<EEnvQueryRunMode::Type> QueryingMode;
|
||||
|
||||
UPROPERTY(Category = EQS, EditAnywhere)
|
||||
FNavAgentProperties NavAgentProperties;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
private:
|
||||
/** Editor Preview */
|
||||
UPROPERTY(Transient)
|
||||
UEQSRenderingComponent* EdRenderComp;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
protected:
|
||||
TSharedPtr<FEnvQueryInstance> QueryInstance;
|
||||
|
||||
TArray<FEnvQueryInstance> StepResults;
|
||||
|
||||
public:
|
||||
/** This pawn class spawns its controller in PostInitProperties to have it available in editor mode*/
|
||||
virtual void TickActor( float DeltaTime, enum ELevelTick TickType, FActorTickFunction& ThisTickFunction ) override;
|
||||
virtual void PostLoad() override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
virtual void PostEditMove(bool bFinished) override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
// IEQSQueryResultSourceInterface start
|
||||
virtual const FEnvQueryResult* GetQueryResult() const override;
|
||||
virtual const FEnvQueryInstance* GetQueryInstance() const override;
|
||||
|
||||
virtual bool GetShouldDebugDrawLabels() const override { return bDrawLabels; }
|
||||
virtual bool GetShouldDrawFailedItems() const override{ return bDrawFailedItems; }
|
||||
virtual float GetHighlightRangePct() const override;
|
||||
// IEQSQueryResultSourceInterface end
|
||||
|
||||
// INavAgentInterface begin
|
||||
virtual const FNavAgentProperties& GetNavAgentPropertiesRef() const override;
|
||||
// INavAgentInterface end
|
||||
|
||||
void RunEQSQuery();
|
||||
|
||||
protected:
|
||||
void Reset() override;
|
||||
void MakeOneStep();
|
||||
|
||||
void UpdateDrawing();
|
||||
|
||||
#if WITH_EDITOR
|
||||
static void OnEditorSelectionChanged(UObject* NewSelection);
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
public:
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** Returns EdRenderComp subobject **/
|
||||
UEQSRenderingComponent* GetEdRenderComp() { return EdRenderComp; }
|
||||
#endif
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "EnvQuery.generated.h"
|
||||
|
||||
class UEdGraph;
|
||||
class UEnvQueryOption;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
class UEdGraph;
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class AIMODULE_API UEnvQuery : public UDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
/** Graph for query */
|
||||
UPROPERTY()
|
||||
UEdGraph* EdGraph;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend class UEnvQueryManager;
|
||||
|
||||
UPROPERTY()
|
||||
FName QueryName;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UEnvQueryOption*> Options;
|
||||
|
||||
public:
|
||||
/** Gather all required named params */
|
||||
void CollectQueryParams(UObject& QueryOwner, TArray<FAIDynamicParam>& NamedValues) const;
|
||||
|
||||
virtual void PostInitProperties() override;
|
||||
|
||||
/** QueryName patching up */
|
||||
virtual void PostLoad() override;
|
||||
#if WITH_EDITOR
|
||||
virtual void PostDuplicate(bool bDuplicateForPIE) override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
FName GetQueryName() const { return QueryName; }
|
||||
|
||||
TArray<UEnvQueryOption*>& GetOptionsMutable() { return Options; }
|
||||
const TArray<UEnvQueryOption*>& GetOptions() const { return Options; }
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "EnvQueryContext.generated.h"
|
||||
|
||||
struct FEnvQueryContextData;
|
||||
struct FEnvQueryInstance;
|
||||
|
||||
UCLASS(Abstract, EditInlineNew)
|
||||
class AIMODULE_API UEnvQueryContext : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
virtual void ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const;
|
||||
};
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "EngineDefines.h"
|
||||
#include "EnvironmentQuery/EnvQueryTypes.h"
|
||||
#include "VisualLogger/VisualLogger.h"
|
||||
#include "DebugRenderSceneProxy.h"
|
||||
#include "EnvQueryDebugHelpers.generated.h"
|
||||
|
||||
class FTestData;
|
||||
class UEnvQueryDebugHelpers;
|
||||
|
||||
#if USE_EQS_DEBUGGER || ENABLE_VISUAL_LOG
|
||||
|
||||
struct FLogCategoryBase;
|
||||
|
||||
namespace EQSDebug
|
||||
{
|
||||
struct FItemData
|
||||
{
|
||||
FString Desc;
|
||||
int32 ItemIdx;
|
||||
float TotalScore;
|
||||
|
||||
TArray<float> TestValues;
|
||||
TArray<float> TestScores;
|
||||
};
|
||||
|
||||
struct FTestData
|
||||
{
|
||||
FString ShortName;
|
||||
FString Detailed;
|
||||
};
|
||||
|
||||
// struct filled while collecting data (to store additional debug data needed to display per rendered item)
|
||||
struct FDebugHelper
|
||||
{
|
||||
FDebugHelper() : Location(FVector::ZeroVector), Radius(0), FailedTestIndex(INDEX_NONE){}
|
||||
FDebugHelper(FVector Loc, float R) : Location(Loc), Radius(R), FailedTestIndex(INDEX_NONE) {}
|
||||
FDebugHelper(FVector Loc, float R, const FString& Desc) : Location(Loc), Radius(R), FailedTestIndex(INDEX_NONE), AdditionalInformation(Desc) {}
|
||||
|
||||
FVector Location;
|
||||
float Radius;
|
||||
int32 FailedTestIndex;
|
||||
float FailedScore;
|
||||
FString AdditionalInformation;
|
||||
};
|
||||
|
||||
struct FQueryData
|
||||
{
|
||||
TArray<FItemData> Items;
|
||||
TArray<FTestData> Tests;
|
||||
TArray<FDebugRenderSceneProxy::FSphere> SolidSpheres;
|
||||
TArray<FDebugRenderSceneProxy::FText3d> Texts;
|
||||
TArray<FDebugHelper> RenderDebugHelpers;
|
||||
TArray<FString> Options;
|
||||
int32 UsedOption;
|
||||
int32 NumValidItems;
|
||||
int32 Id;
|
||||
FString Name;
|
||||
float Timestamp;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
UsedOption = 0;
|
||||
Options.Reset();
|
||||
NumValidItems = 0;
|
||||
Id = INDEX_NONE;
|
||||
Name.Empty();
|
||||
Items.Reset();
|
||||
Tests.Reset();
|
||||
SolidSpheres.Reset();
|
||||
Texts.Reset();
|
||||
Timestamp = 0;
|
||||
RenderDebugHelpers.Reset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, FDebugRenderSceneProxy::FSphere& Data)
|
||||
{
|
||||
Ar << Data.Radius;
|
||||
Ar << Data.Location;
|
||||
Ar << Data.Color;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, FDebugRenderSceneProxy::FText3d& Data)
|
||||
{
|
||||
Ar << Data.Text;
|
||||
Ar << Data.Location;
|
||||
Ar << Data.Color;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, EQSDebug::FItemData& Data)
|
||||
{
|
||||
Ar << Data.Desc;
|
||||
Ar << Data.ItemIdx;
|
||||
Ar << Data.TotalScore;
|
||||
Ar << Data.TestValues;
|
||||
Ar << Data.TestScores;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, EQSDebug::FTestData& Data)
|
||||
{
|
||||
Ar << Data.ShortName;
|
||||
Ar << Data.Detailed;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, EQSDebug::FDebugHelper& Data)
|
||||
{
|
||||
Ar << Data.Location;
|
||||
Ar << Data.Radius;
|
||||
Ar << Data.AdditionalInformation;
|
||||
Ar << Data.FailedTestIndex;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
inline
|
||||
FArchive& operator<<(FArchive& Ar, EQSDebug::FQueryData& Data)
|
||||
{
|
||||
Ar << Data.Items;
|
||||
Ar << Data.Tests;
|
||||
Ar << Data.SolidSpheres;
|
||||
Ar << Data.Texts;
|
||||
Ar << Data.NumValidItems;
|
||||
Ar << Data.Id;
|
||||
Ar << Data.Name;
|
||||
Ar << Data.Timestamp;
|
||||
Ar << Data.RenderDebugHelpers;
|
||||
Ar << Data.Options;
|
||||
Ar << Data.UsedOption;
|
||||
return Ar;
|
||||
}
|
||||
|
||||
#endif //USE_EQS_DEBUGGER || ENABLE_VISUAL_LOG
|
||||
|
||||
#if ENABLE_VISUAL_LOG && USE_EQS_DEBUGGER
|
||||
# define UE_VLOG_EQS(Query, Category, Verbosity) UEnvQueryDebugHelpers::LogQuery(Query, Category, ELogVerbosity::Verbosity);
|
||||
#else
|
||||
# define UE_VLOG_EQS(Query, CategoryName, Verbosity)
|
||||
#endif //ENABLE_VISUAL_LOG && USE_EQS_DEBUGGER
|
||||
|
||||
UCLASS(Abstract)
|
||||
class AIMODULE_API UEnvQueryDebugHelpers : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
#if USE_EQS_DEBUGGER
|
||||
static void QueryToDebugData(FEnvQueryInstance& Query, EQSDebug::FQueryData& EQSLocalData, int32 MaxItemsToStore = 10);
|
||||
static void QueryToBlobArray(FEnvQueryInstance& Query, TArray<uint8>& BlobArray, bool bUseCompression = false);
|
||||
static void DebugDataToBlobArray(EQSDebug::FQueryData& QueryData, TArray<uint8>& BlobArray, bool bUseCompression = false);
|
||||
static void BlobArrayToDebugData(const TArray<uint8>& BlobArray, EQSDebug::FQueryData& EQSLocalData, bool bUseCompression = false);
|
||||
#endif
|
||||
|
||||
#if ENABLE_VISUAL_LOG && USE_EQS_DEBUGGER
|
||||
static void LogQuery(FEnvQueryInstance& Query, const FLogCategoryBase& Category, ELogVerbosity::Type Verbosity);
|
||||
static void LogQuery(FEnvQueryInstance& Query, const FName& CategoryName, ELogVerbosity::Type Verbosity);
|
||||
|
||||
private:
|
||||
static void LogQueryInternal(FEnvQueryInstance& Query, const FName& CategoryName, ELogVerbosity::Type Verbosity, float TimeSeconds, FVisualLogEntry *CurrentEntry);
|
||||
#endif
|
||||
};
|
||||
|
||||
#if ENABLE_VISUAL_LOG && USE_EQS_DEBUGGER
|
||||
inline void UEnvQueryDebugHelpers::LogQuery(FEnvQueryInstance& Query, const FLogCategoryBase& Category, ELogVerbosity::Type Verbosity)
|
||||
{
|
||||
const FName CategoryName = Category.GetCategoryName();
|
||||
LogQuery(Query, CategoryName, Verbosity);
|
||||
}
|
||||
|
||||
inline void UEnvQueryDebugHelpers::LogQuery(FEnvQueryInstance& Query, const FName& CategoryName, ELogVerbosity::Type Verbosity)
|
||||
{
|
||||
UWorld *World = nullptr;
|
||||
FVisualLogEntry *CurrentEntry = nullptr;
|
||||
if (FVisualLogger::CheckVisualLogInputInternal(Query.Owner.Get(), CategoryName, Verbosity, &World, &CurrentEntry) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogQueryInternal(Query, CategoryName, Verbosity, World->TimeSeconds, CurrentEntry);
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user