LEAP Documentation 40220
Documentation for the LEAP project
ProjectXAIController.h
Go to the documentation of this file.
1// Copyright Blue Isle Studios 2017. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
7#include "BehaviorTree/BlackboardComponent.h"
9#include "DetourCrowdAIController.h"
10#include "ProjectXAIController.generated.h"
11
12class APlayerState;
14class UVehicleSeatComponent;
16
17#define BLACKBOARDKEY_TARGET FName("Target")
18#define BLACKBOARDKEY_MOVEWAYPOINT FName("MoveWaypoint")
19#define BLACKBOARDKEY_SETTINGTARGET FName("IsSwitchingTargets")
20#define BLACKBOARDKEY_RANGEMIN FName("EngagementRangeMin")
21#define BLACKBOARDKEY_RANGEMAX FName("EngagementRangeMax")
22#define BLACKBOARDKEY_MAXFIRINGDISTANCE FName("FiringDistance")
23#define BLACKBOARDKEY_VISIBILITYEXTENT FName("VisibilityExtent")
24#define BLACKBOARDKEY_AGENTHEIGHT FName("AgentHeight")
25#define BLACKBOARDKEY_TARGET_THREATLEVEL FName("TargetThreatLevel")
26
27UENUM(BlueprintType)
28enum class ESetTargetEvent : uint8
29{
30 NoReason = 0,
33 SawTarget = 3,
34 HeardTarget = 4,
36 TargetLost = 6,
37 TargetKilled = 7,
41};
42
43UENUM(BlueprintType)
44enum class EAcquireTargetType : uint8
45{
46 Random = 0,
47 Closest = 1
48};
49
50UCLASS()
51class PROJECTX_API AProjectXAIController : public ADetourCrowdAIController, public ITeamInterface
52{
53 GENERATED_BODY()
54
55public:
56 /* Should the AI switch targets if attacked? */
57 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
58 FText DisplayName = NSLOCTEXT("LEAP", "AI_DisplayName", "Bot");
59 /* When the behaviour tree reports a failure (pathing, eqs failures etc), we'll increment a counter which is reset if the behaviour tree succeeds. If the value goes above our threshold, the pawn assumed lost for gameplay purposes and is terminated. -1 disables this behaviour */
60 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
61 int32 AllowableSimultaneousFailures = -1.0f;
62 /* Should we automatically select a target when the pawn is posessed? */
63 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
64 bool bSelectTargetOnPosssess = false;
65 /* Should the AI target the player's head? They will do a lot more damage on these shots. If false, will target the body.*/
66 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
67 bool bAllowHeadshots = false;
68 /* Should the AI switch targets if attacked? */
69 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
70 bool bTargetAttackers = true;
71 /* If enabled, allies will be able to be targeted. Make sure your ai's behaviours account for this if enabled. */
72 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
73 bool bCanTargetAllies = false;
74 /* If threat reaches zero, should we drop ally targets? Hostile targets are never dropped at zero threat. Low threat merely gives them an avenue to switch to higher threat targets */
75 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI", meta = (EditCondition = "bCanTargetAllies"))
76 bool bDropAllyTargetsIfThreatIsZero = false;
77 /* Should the AI be capable of losing its target? */
78 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
79 bool CanLoseTarget = false;
80 /*If the AI has a target, it will check every X seconds and lose the target if it is no longer visible*/
81 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI", meta=(EditCondition="CanLoseTarget"))
82 float AttentionSpan = 3.0f;
83 /* Wait a number of seconds before acquiring the target and running behaviours. This is useful if you want to the AI to appear reactive before beginning behaviours. */
84 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
85 TMap<ESetTargetEvent, float> TargetSwitchDelay;
86 /* How many points of threat are decayed per second? Reaching zero, could cause the AI to drop the target depending on settings */
87 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
88 float ThreatDecayRate = 1.0f;
89 /* The ai is allowed to fire if outside of the engagement distance so long as they are within the following range. This value should always be larger or equal to your maximum engagement distance */
90 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
91 float MaxFiringDistance = 8000.0f;
92 /* The distance from the target that the AI would like to path towards. */
93 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
94 FVector2D EngagementDistance = FVector2D(1000.0f, 5000.0f);
95 /* Updates the blackboard extent trace size which allows the AI to pass or fail occlusion checks. You will want to use a size similar to the AI's weapon projectiles extent. */
96 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
97 float VisibilityExtentTrace = 25.0f;
98 /* Tolerance to allow in case pathfinding finishes queries just outside or inside of the expected bounds */
99 UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI")
100 float EngagementRangePadding = 300.0f;
101 UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "AI Components")
102 UProjectXAIPerception* PerceptionSystem = nullptr;
103
105
106 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
107 AProjectXCharacter* GetProjectXAI() const;
108 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
109 float GetTargetThreatLevel() const;
110 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
111 FORCEINLINE bool HasTarget() const { return GetTarget() != nullptr; }
112 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
113 virtual UObject* GetTarget() const;
114 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
115 virtual bool CanSeeTarget() const { return bCanSeeTarget; }
116 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
117 virtual bool IsWithinEngagementMaxRangeOfTarget() const { return bIsWithinEngagementMaxRangeOfTarget; }
118 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
119 virtual bool IsWithinEngagementRangeOfTarget() const { return bIsWithinEngagementRangeOfTarget; }
120 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
121 virtual bool IsWithinFiringRangeOfTarget() const { return bIsWithinFiringRangeOfTarget; }
122 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
123 virtual float GetSquareFiringDistance() const { return FiringDistanceSquared; }
124 UFUNCTION(BlueprintPure, BlueprintAuthorityOnly, Category = "AI")
125 virtual const FVector2D& GetSquareEngagementDistance() const { return EngagementDistanceSquared; }
126
127 UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "AI")
128 virtual void SetTarget(AActor* Target, ESetTargetEvent Context, bool bAllowDelays = true, float TargetThreatLevel = 1.0f);
129
130 UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "AI")
131 virtual bool SelectTarget(bool bDontReselectSameTarget, EAcquireTargetType SearchType);
132 UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "AI")
133 virtual AActor* GetMoveActor() const { return MoveActor; }
134
135 virtual void SetCanSeeTarget(bool bToggle) { bCanSeeTarget = bToggle; }
136 virtual void SetIsWithinEngagementMaxRangeOfTarget(bool bToggle) { bIsWithinEngagementMaxRangeOfTarget = bToggle; }
137 virtual void SetIsWithinEngagementRangeOfTarget(bool bToggle) { bIsWithinEngagementRangeOfTarget = bToggle; }
138 virtual void SetIsWithinFiringRangeOfTarget(bool bToggle) { bIsWithinFiringRangeOfTarget = bToggle; }
139
140 template <class T>
141 T* GetTarget() const
142 {
143 if (GetBlackboardComponent())
144 {
145 return Cast<T>(GetBlackboardComponent()->GetValueAsObject(BLACKBOARDKEY_TARGET));
146 }
147 return nullptr;
148 }
149
150protected:
151 virtual void BeginPlay() override;
152 virtual void CheckIfStuck();
153 virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
154 virtual void UpdateCanLoseTarget();
155 virtual void UpdateThreatDecay();
156 virtual void OnBehaviourTreeFailureReported();
157 virtual void OnBehaviourTreeSuccess();
158 virtual void OnPossess(APawn* InPawn) override;
159 virtual void OnUnPossess() override;
160 virtual int32 GetTeam() const override;
161 virtual int32 SetTeam(int32 NewTeam) override;
162 virtual FVector GetFocalPointOnActor(const AActor* Actor) const override;
163
164 UFUNCTION()
165 void OnTargetKilled(class AActor* Victim, const float Damage, struct FDamageEvent const& DamageEvent, const class AController* EventInstigator, const class AActor* DamageCauser, const class APlayerState* InstigatorPlayerState);
166 UFUNCTION()
167 void OnTargetVehicleEnter(AProjectXCharacter* Driver, AProjectXVehicle* CurrentVehicle, AProjectXVehicle* PreviousVehicle);
168 UFUNCTION()
169 void OnTargetVehicleExit(AProjectXVehicle* Vehicle, UVehicleSeatComponent* Seat, AProjectXCharacter* PreviousPassenger);
170 UFUNCTION()
171 void OnPawnDeath(class AActor* Victim, const float Damage, struct FDamageEvent const& DamageEvent, const class AController* EventInstigator, const class AActor* DamageCauser, const class APlayerState* InstigatorPlayerState);
172 UFUNCTION()
173 virtual void OnPerceptionUpdated(TArray<FProjectXPerceptionInfo> Perceptions);
174
175private:
176 mutable AProjectXCharacter* CachedPawn = nullptr;
177 FTimerHandle UpdateTargetTimerHandle;
178 FTimerHandle ThreatDecayTimerHandle;
179 FTimerHandle TargetSwitchDelayTimerHandle;
180 AActor* MoveActor = nullptr;
181 FVector SpawnLocation = FVector::ZeroVector;
182 int32 FailCounter = 0;
183 bool bCanSeeTarget = false;
184 bool bIsWithinEngagementMaxRangeOfTarget = false;
185 bool bIsWithinEngagementRangeOfTarget = false;
186 bool bIsWithinFiringRangeOfTarget = false;
187 float FiringDistanceSquared = 0.0f;
188 FVector2D EngagementDistanceSquared = FVector2D::ZeroVector;
189 FVector CachedPawnPosition = FVector::ZeroVector;
190};
#define BLACKBOARDKEY_TARGET
Definition: ProjectXAIController.h:17
EAcquireTargetType
Definition: ProjectXAIController.h:45
ESetTargetEvent
Definition: ProjectXAIController.h:29
Definition: ProjectXAIController.h:52
T * GetTarget() const
Definition: ProjectXAIController.h:141
virtual void SetCanSeeTarget(bool bToggle)
Definition: ProjectXAIController.h:135
virtual void SetIsWithinEngagementRangeOfTarget(bool bToggle)
Definition: ProjectXAIController.h:137
virtual void SetIsWithinFiringRangeOfTarget(bool bToggle)
Definition: ProjectXAIController.h:138
virtual void SetIsWithinEngagementMaxRangeOfTarget(bool bToggle)
Definition: ProjectXAIController.h:136
Definition: ProjectXCharacter.h:128
virtual int32 GetTeam() const override
Definition: ProjectXCharacter.cpp:1855
TWeakObjectPtr< AProjectXVehicle > PreviousVehicle
Definition: ProjectXCharacter.h:714
virtual void BeginPlay() override
Definition: ProjectXCharacter.cpp:179
TWeakObjectPtr< AProjectXVehicle > Vehicle
Definition: ProjectXCharacter.h:711
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
Definition: ProjectXCharacter.cpp:1207
virtual int32 SetTeam(int32 NewTeam) override
Definition: ProjectXCharacter.cpp:1870
Definition: ProjectXVehicle.h:56
Definition: TeamInterface.h:26
Definition: ProjectXAIPerception.h:36