From d6325b373dbdc9084b1cab376a1b7480f9b68a28 Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Tue, 31 Mar 2026 18:20:04 +0200 Subject: [PATCH] Fix IsCoverNeeded decorator: resolve AimTargetActor to owning Pawn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - IsCoverNeeded used Cast on ThreatActor which failed for AimTargetActors → always returned true (assume dangerous) → enemies took cover against civilians - Fix: use FindOwningPawn to walk Owner/Instigator chain to the actual Pawn - Revert inline civilian check in EvaluateReaction (decorator handles it in BT) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../BT/PS_AI_Behavior_BTDecorator_IsCoverNeeded.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 6febf3c..245b29c 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 @@ -2,6 +2,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_Interface.h" #include "BehaviorTree/BlackboardComponent.h" @@ -23,11 +24,11 @@ bool UPS_AI_Behavior_BTDecorator_IsCoverNeeded::CalculateRawConditionValue( AActor* ThreatActor = Cast(BB->GetValueAsObject(PS_AI_Behavior_BB::ThreatActor)); if (!ThreatActor) return false; - // If the target doesn't implement the interface, assume dangerous (safe default) - APawn* ThreatPawn = Cast(ThreatActor); + // Resolve ThreatActor to owning Pawn (AimTargetActor → Character) + APawn* ThreatPawn = UPS_AI_Behavior_PerceptionComponent::FindOwningPawn(ThreatActor); if (!ThreatPawn || !ThreatPawn->Implements()) { - return true; + return true; // Can't resolve → assume dangerous (safe default) } const EPS_AI_Behavior_NPCType TargetType =