diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.dll b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.dll index 489c3a7..4efa474 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.dll and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.dll differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.exp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.exp index 5562d5e..8acac19 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.exp and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.exp differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.exe b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.exe index 5573ec5..52e6e9e 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.exe and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.exe differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.pdb index 24a141a..8695149 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_0.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.exe b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.exe index 4c31aa9..b383d63 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.exe and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.exe differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.pdb index f274404..a7a5b2d 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_1.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.exe b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.exe index cdbfe69..caef3cb 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.exe and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.exe differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.pdb index 76f1128..dff3741 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_2.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.exe b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.exe index 19e2ea6..8bfaca5 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.exe and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.exe differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.pdb index 65c8273..5c7bf48 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_3.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.exe b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.exe index 5a6245c..55845b3 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.exe and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.exe differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.pdb index 2e009ba..ca1c610 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.patch_4.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.pdb index aec1eac..2afa902 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.dll b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.dll index 43ffd49..152505c 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.dll and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.dll differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.exp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.exp index 4f83f9f..996d269 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.exp and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.exp differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.pdb index 73b106e..0e3e3c2 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.cpp index 245b29c..7e53619 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.cpp @@ -3,6 +3,7 @@ #include "BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.h" #include "PS_AI_Behavior_AIController.h" #include "PS_AI_Behavior_PerceptionComponent.h" +#include "PS_AI_Behavior_PersonalityComponent.h" #include "PS_AI_Behavior_Interface.h" #include "BehaviorTree/BlackboardComponent.h" @@ -34,7 +35,22 @@ bool UPS_AI_Behavior_BTDecorator_IsCoverNeeded::CalculateRawConditionValue( const EPS_AI_Behavior_NPCType TargetType = IPS_AI_Behavior_Interface::Execute_GetBehaviorNPCType(ThreatPawn); - return DangerousTargetTypes.Contains(TargetType); + if (!DangerousTargetTypes.Contains(TargetType)) + { + return false; // Target is not dangerous → no cover needed + } + + // Check personality-driven combat/cover cycle timer + APS_AI_Behavior_AIController* AIC = Cast(OwnerComp.GetAIOwner()); + if (AIC) + { + if (const UPS_AI_Behavior_PersonalityComponent* Personality = AIC->GetPersonalityComponent()) + { + return Personality->ShouldPreferCover(); + } + } + + return true; // No personality → default to cover } FString UPS_AI_Behavior_BTDecorator_IsCoverNeeded::GetStaticDescription() const diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_AIController.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_AIController.cpp index b9130c2..0df463c 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_AIController.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_AIController.cpp @@ -17,6 +17,7 @@ #include "BehaviorTree/Blackboard/BlackboardKeyType_Object.h" #include "BehaviorTree/Blackboard/BlackboardKeyType_Vector.h" #include "BehaviorTree/Blackboard/BlackboardKeyType_String.h" +#include "BehaviorTree/Blackboard/BlackboardKeyType_Bool.h" APS_AI_Behavior_AIController::APS_AI_Behavior_AIController() { @@ -184,6 +185,12 @@ void APS_AI_Behavior_AIController::SetupBlackboard() ThreatPawnNameEntry.EntryName = PS_AI_Behavior_BB::ThreatPawnName; ThreatPawnNameEntry.KeyType = NewObject(BlackboardAsset); BlackboardAsset->Keys.Add(ThreatPawnNameEntry); + + // PreferCover (bool: personality-driven combat/cover cycle) + FBlackboardEntry PreferCoverEntry; + PreferCoverEntry.EntryName = PS_AI_Behavior_BB::PreferCover; + PreferCoverEntry.KeyType = NewObject(BlackboardAsset); + BlackboardAsset->Keys.Add(PreferCoverEntry); } UBlackboardComponent* RawBBComp = nullptr; diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp index 6fe1bc7..f4f7fe2 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp @@ -102,11 +102,6 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::EvaluateReaction() c if (PerceivedThreatLevel >= EffectiveAttackThresh && Aggressivity > 0.3f) { - // Cautious NPCs prefer cover over direct combat - if (Caution > 0.6f) - { - return EPS_AI_Behavior_State::TakingCover; - } return EPS_AI_Behavior_State::Combat; } @@ -138,7 +133,81 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::ApplyReaction() return CurrentState; } - const EPS_AI_Behavior_State NewState = EvaluateReaction(); + EPS_AI_Behavior_State NewState = EvaluateReaction(); + + // ─── Combat/Cover cycle timer ────────────────────────────────── + // While in Combat, alternate bPreferCover flag based on personality ratio. + // Writes PreferCover bool to Blackboard so BT decorators can react via observer aborts. + if (NewState == EPS_AI_Behavior_State::Combat) + { + if (!bCombatCoverCycleActive) + { + // Start the cycle — begin with cover if cautious, attack if aggressive + bCombatCoverCycleActive = true; + const float Aggressivity = GetTrait(EPS_AI_Behavior_TraitAxis::Aggressivity); + const float Caution = GetTrait(EPS_AI_Behavior_TraitAxis::Caution); + const float CombatRatio = (Aggressivity + Caution > 0.0f) + ? Aggressivity / (Aggressivity + Caution) : 0.5f; + bPreferCover = (CombatRatio <= 0.5f); + CombatCoverTimer = CalculatePhaseDuration( + bPreferCover ? EPS_AI_Behavior_State::TakingCover : EPS_AI_Behavior_State::Combat); + + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Combat/Cover cycle started: %s for %.1fs"), + *GetOwner()->GetName(), bPreferCover ? TEXT("Cover") : TEXT("Attack"), CombatCoverTimer); + } + else + { + // Tick down the timer (ApplyReaction is called every ~0.5s by the BT service) + CombatCoverTimer -= 0.5f; + + if (CombatCoverTimer <= 0.0f) + { + // Switch phase + bPreferCover = !bPreferCover; + CombatCoverTimer = CalculatePhaseDuration( + bPreferCover ? EPS_AI_Behavior_State::TakingCover : EPS_AI_Behavior_State::Combat); + + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Combat/Cover cycle switch: → %s for %.1fs"), + *GetOwner()->GetName(), bPreferCover ? TEXT("Cover") : TEXT("Attack"), CombatCoverTimer); + } + } + + // Write to BB so Blackboard-based decorators can observe the change + if (AActor* Owner = GetOwner()) + { + if (AAIController* AIC = Cast(Cast(Owner) ? + Cast(Owner)->GetController() : nullptr)) + { + if (UBlackboardComponent* BB = AIC->GetBlackboardComponent()) + { + BB->SetValueAsBool(PS_AI_Behavior_BB::PreferCover, bPreferCover); + } + } + } + } + else + { + // Left combat → reset cycle + if (bCombatCoverCycleActive) + { + bCombatCoverCycleActive = false; + bPreferCover = false; + CombatCoverTimer = 0.0f; + + if (AActor* Owner = GetOwner()) + { + if (AAIController* AIC = Cast(Cast(Owner) ? + Cast(Owner)->GetController() : nullptr)) + { + if (UBlackboardComponent* BB = AIC->GetBlackboardComponent()) + { + BB->SetValueAsBool(PS_AI_Behavior_BB::PreferCover, false); + } + } + } + } + } + if (NewState != CurrentState) { const EPS_AI_Behavior_State OldState = CurrentState; @@ -155,6 +224,32 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::ApplyReaction() return CurrentState; } +float UPS_AI_Behavior_PersonalityComponent::CalculatePhaseDuration(EPS_AI_Behavior_State Phase) const +{ + const float Aggressivity = GetTrait(EPS_AI_Behavior_TraitAxis::Aggressivity); + const float Caution = GetTrait(EPS_AI_Behavior_TraitAxis::Caution); + const float CycleDuration = Profile ? Profile->CombatCoverCycleDuration : 15.0f; + + const float Sum = Aggressivity + Caution; + const float CombatRatio = (Sum > 0.0f) ? Aggressivity / Sum : 0.5f; + + float Duration; + if (Phase == EPS_AI_Behavior_State::Combat) + { + Duration = CycleDuration * CombatRatio; + } + else + { + Duration = CycleDuration * (1.0f - CombatRatio); + } + + // Clamp minimum 2s, add ±20% jitter + Duration = FMath::Max(Duration, 2.0f); + Duration *= FMath::RandRange(0.8f, 1.2f); + + return Duration; +} + void UPS_AI_Behavior_PersonalityComponent::ForceState(EPS_AI_Behavior_State NewState) { // Only server can change replicated state diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Definitions.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Definitions.h index 7fb3b71..b3b9ace 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Definitions.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Definitions.h @@ -189,4 +189,5 @@ namespace PS_AI_Behavior_BB inline const FName CombatSubState = TEXT("CombatSubState"); inline const FName LastKnownTargetPosition = TEXT("LastKnownTargetPosition"); inline const FName ThreatPawnName = TEXT("ThreatPawnName"); // Debug: name of the owning Pawn behind ThreatActor + inline const FName PreferCover = TEXT("PreferCover"); // Bool: personality-driven cover preference cycle } diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityComponent.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityComponent.h index 4eb4a82..eb4fa6f 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityComponent.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityComponent.h @@ -109,6 +109,14 @@ public: UFUNCTION(BlueprintCallable, Category = "PS AI Behavior|Personality") EPS_AI_Behavior_NPCType GetNPCType() const; + /** + * Whether the NPC currently prefers cover over direct attack. + * Driven by the Combat/Cover cycle timer based on Aggressivity vs Caution. + * Used by the IsCoverNeeded BT decorator. + */ + UFUNCTION(BlueprintCallable, Category = "PS AI Behavior|Personality") + bool ShouldPreferCover() const { return bPreferCover; } + // ─── Replication ──────────────────────────────────────────────────── virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; @@ -130,6 +138,20 @@ private: */ void HandleStateChanged(EPS_AI_Behavior_State OldState, EPS_AI_Behavior_State NewState); + // ─── Combat/Cover Cycle Timer ────────────────────────────────────── + + /** Countdown timer for the current Combat or TakingCover phase. */ + float CombatCoverTimer = 0.0f; + + /** Whether the combat/cover cycle timer is active. */ + bool bCombatCoverCycleActive = false; + + /** Current cover preference — toggled by the cycle timer. */ + bool bPreferCover = false; + + /** Calculate the duration for a Combat or TakingCover phase based on personality. */ + float CalculatePhaseDuration(EPS_AI_Behavior_State Phase) const; + /** Draw floating debug text above the NPC's head. */ void DrawDebugInfo() const; }; diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityProfile.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityProfile.h index 83ba50f..df2e089 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityProfile.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_PersonalityProfile.h @@ -110,6 +110,18 @@ public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Personality|Combat", meta = (ClampMin = "50.0")) float MaxAttackRange = 300.0f; + // ─── Combat/Cover Cycle ──────────────────────────────────────────── + + /** + * Base duration (seconds) of the Combat↔TakingCover cycle. + * The actual time in each state is proportional to Aggressivity vs Caution: + * Combat duration = CombatCoverCycleDuration × Aggressivity / (Aggressivity + Caution) + * TakingCover duration = CombatCoverCycleDuration × Caution / (Aggressivity + Caution) + */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Personality|Combat", + meta = (ClampMin = "4.0", ClampMax = "60.0")) + float CombatCoverCycleDuration = 15.0f; + // ─── Movement Speed per State ────────────────────────────────────── /**