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 9fbf803..164cc95 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 6b073f7..0b5801b 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.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_Behavior.pdb index ee73809..4e0813b 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 5e25371..70a69f0 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.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Binaries/Win64/UnrealEditor-PS_AI_BehaviorEditor.pdb index 2a8fd2d..d565db5 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_BTService_UpdateThreat.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTService_UpdateThreat.cpp index 6a851f4..cb0ad86 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTService_UpdateThreat.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTService_UpdateThreat.cpp @@ -40,19 +40,22 @@ void UPS_AI_Behavior_BTService_UpdateThreat::TickNode( // Debug: check what perception sees TArray PerceivedActors; Perception->GetCurrentlyPerceivedActors(nullptr, PerceivedActors); - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] UpdateThreat: Perceived %d actors"), - *AIC->GetName(), PerceivedActors.Num()); - for (AActor* A : PerceivedActors) + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) { - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT(" - %s"), *A->GetName()); + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] UpdateThreat: Perceived %d actors"), + *AIC->GetName(), PerceivedActors.Num()); + for (AActor* A : PerceivedActors) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT(" - %s"), *A->GetName()); + } } // Also check known actors (perceived in the past but maybe lost sight) TArray KnownActors; Perception->GetKnownPerceivedActors(nullptr, KnownActors); - if (KnownActors.Num() != PerceivedActors.Num()) + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn()) && KnownActors.Num() != PerceivedActors.Num()) { - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] UpdateThreat: Known (past) %d actors"), + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] UpdateThreat: Known (past) %d actors"), *AIC->GetName(), KnownActors.Num()); } @@ -74,8 +77,11 @@ void UPS_AI_Behavior_BTService_UpdateThreat::TickNode( BB->SetValueAsFloat(PS_AI_Behavior_BB::ThreatLevel, FinalThreat); - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] UpdateThreat: raw=%.2f, stored=%.2f, final=%.2f"), - *AIC->GetName(), RawThreat, StoredThreat, FinalThreat); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] UpdateThreat: raw=%.2f, stored=%.2f, final=%.2f"), + *AIC->GetName(), RawThreat, StoredThreat, FinalThreat); + } // ─── Update threat actor and location with LOS tracking ───────── FUpdateThreatMemory* Memory = reinterpret_cast(NodeMemory); diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindAndFollowSpline.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindAndFollowSpline.cpp index c27b2d2..c8b109b 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindAndFollowSpline.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindAndFollowSpline.cpp @@ -6,6 +6,7 @@ #include "PS_AI_Behavior_SplineNetwork.h" #include "PS_AI_Behavior_SplinePath.h" #include "PS_AI_Behavior_PersonalityComponent.h" +#include "PS_AI_Behavior_Statics.h" #include "PS_AI_Behavior_Definitions.h" #include "Navigation/PathFollowingComponent.h" @@ -32,10 +33,13 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( } // Debug: log state on entry - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindAndFollowSpline: bIsFollowing=%d CurrentSpline=%s"), - *AIC->GetName(), - (int32)Follower->bIsFollowing, - Follower->CurrentSpline ? *Follower->CurrentSpline->GetName() : TEXT("null")); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindAndFollowSpline: bIsFollowing=%d CurrentSpline=%s"), + *AIC->GetName(), + (int32)Follower->bIsFollowing, + Follower->CurrentSpline ? *Follower->CurrentSpline->GetName() : TEXT("null")); + } // If already following a spline, don't re-search — just succeed immediately // The Follow Spline task will continue the movement @@ -59,10 +63,13 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( const FVector SplineDir = Follower->CurrentSpline->GetWorldDirectionAtDistance(ClosestDist); const bool bForward = FVector::DotProduct(PawnFwd, SplineDir) >= 0.0f; - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindAndFollowSpline: resuming spline '%s' at closest point (gap=%.0fcm, dist=%.0f, bWalkToSpline=%d, AcceptanceRadius=%.0f)"), - *AIC->GetName(), *Follower->CurrentSpline->GetName(), GapToSpline, ClosestDist, - (int32)bWalkToSpline, AcceptanceRadius); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindAndFollowSpline: resuming spline '%s' at closest point (gap=%.0fcm, dist=%.0f, bWalkToSpline=%d, AcceptanceRadius=%.0f)"), + *AIC->GetName(), *Follower->CurrentSpline->GetName(), GapToSpline, ClosestDist, + (int32)bWalkToSpline, AcceptanceRadius); + } if (bWalkToSpline && GapToSpline > AcceptanceRadius) { @@ -73,9 +80,12 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( /*bUsePathfinding=*/true, /*bProjectDestinationToNavigation=*/true, /*bCanStrafe=*/false); - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindAndFollowSpline: MoveToLocation result=%d (0=Failed, 1=AlreadyAtGoal, 2=RequestSuccessful)"), - *AIC->GetName(), (int32)Result); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindAndFollowSpline: MoveToLocation result=%d (0=Failed, 1=AlreadyAtGoal, 2=RequestSuccessful)"), + *AIC->GetName(), (int32)Result); + } if (Result == EPathFollowingRequestResult::AlreadyAtGoal) { @@ -98,9 +108,12 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( { // Close enough — clear any residual movement request and start following AIC->StopMovement(); - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindAndFollowSpline: close enough, StartFollowingAtDistance(dist=%.0f, fwd=%d)"), - *AIC->GetName(), ClosestDist, (int32)bForward); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindAndFollowSpline: close enough, StartFollowingAtDistance(dist=%.0f, fwd=%d)"), + *AIC->GetName(), ClosestDist, (int32)bForward); + } Follower->StartFollowingAtDistance(Follower->CurrentSpline, ClosestDist, bForward); return EBTNodeResult::Succeeded; } @@ -131,9 +144,12 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( AIC->GetPawn()->GetActorLocation(), NPCType, MaxSearchDistance, ClosestSpline, DistAlongSpline)) { - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindAndFollowSpline: no accessible spline within %.0fcm."), - *AIC->GetName(), MaxSearchDistance); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindAndFollowSpline: no accessible spline within %.0fcm."), + *AIC->GetName(), MaxSearchDistance); + } return EBTNodeResult::Failed; } @@ -141,10 +157,13 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( const FVector SplinePoint = ClosestSpline->GetWorldLocationAtDistance(DistAlongSpline); const float GapToSpline = FVector::Dist(AIC->GetPawn()->GetActorLocation(), SplinePoint); - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindAndFollowSpline: found spline '%s' at dist=%.0f/%.0f, gap=%.0fcm"), - *AIC->GetName(), *ClosestSpline->GetName(), DistAlongSpline, - ClosestSpline->GetSplineLength(), GapToSpline); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindAndFollowSpline: found spline '%s' at dist=%.0f/%.0f, gap=%.0fcm"), + *AIC->GetName(), *ClosestSpline->GetName(), DistAlongSpline, + ClosestSpline->GetSplineLength(), GapToSpline); + } if (bWalkToSpline && GapToSpline > AcceptanceRadius) { diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindCover.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindCover.cpp index 72d5694..dc01e77 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindCover.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/BT/PS_AI_Behavior_BTTask_FindCover.cpp @@ -5,6 +5,7 @@ #include "PS_AI_Behavior_Interface.h" #include "PS_AI_Behavior_CoverPoint.h" #include "PS_AI_Behavior_PersonalityComponent.h" +#include "PS_AI_Behavior_Statics.h" #include "PS_AI_Behavior_Definitions.h" #include "BehaviorTree/BlackboardComponent.h" #include "NavigationSystem.h" @@ -122,7 +123,10 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindCover::ExecuteTask( if (BestScore < 0.1f) { - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindCover: no suitable cover found."), *AIC->GetName()); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindCover: no suitable cover found."), *AIC->GetName()); + } return EBTNodeResult::Failed; } @@ -132,17 +136,23 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindCover::ExecuteTask( ChosenPoint->Claim(AIC->GetPawn()); BB->SetValueAsObject(PS_AI_Behavior_BB::CoverPoint, ChosenPoint); - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindCover: using manual %s '%s' (score %.2f)"), - *AIC->GetName(), - ChosenPoint->PointType == EPS_AI_Behavior_CoverPointType::Cover ? TEXT("Cover") : TEXT("HidingSpot"), - *ChosenPoint->GetName(), BestScore); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindCover: using manual %s '%s' (score %.2f)"), + *AIC->GetName(), + ChosenPoint->PointType == EPS_AI_Behavior_CoverPointType::Cover ? TEXT("Cover") : TEXT("HidingSpot"), + *ChosenPoint->GetName(), BestScore); + } } else { BB->ClearValue(PS_AI_Behavior_BB::CoverPoint); - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindCover: using procedural cover (score %.2f)"), - *AIC->GetName(), BestScore); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindCover: using procedural cover (score %.2f)"), + *AIC->GetName(), BestScore); + } } BB->SetValueAsVector(PS_AI_Behavior_BB::CoverLocation, BestCoverPos); @@ -215,10 +225,13 @@ void UPS_AI_Behavior_BTTask_FindCover::TickTask( const FVector CoverLoc = BB->GetValueAsVector(PS_AI_Behavior_BB::CoverLocation); const float DistToCover = FVector::Dist2D(Pawn->GetActorLocation(), CoverLoc); - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] FindCover: MoveStatus=Idle, dist2D=%.0fcm, acceptance=%.0fcm, coverLoc=%s, pawnLoc=%s"), - *AIC->GetName(), DistToCover, AcceptanceRadius, - *CoverLoc.ToString(), *Pawn->GetActorLocation().ToString()); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(AIC->GetPawn())) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] FindCover: MoveStatus=Idle, dist2D=%.0fcm, acceptance=%.0fcm, coverLoc=%s, pawnLoc=%s"), + *AIC->GetName(), DistToCover, AcceptanceRadius, + *CoverLoc.ToString(), *Pawn->GetActorLocation().ToString()); + } if (DistToCover > AcceptanceRadius * 2.0f) { @@ -445,8 +458,11 @@ void UPS_AI_Behavior_BTTask_FindCover::RunRefinementQuery( &UPS_AI_Behavior_BTTask_FindCover::OnRefinementQueryFinished, &OwnerComp, NodeMemory, CoverCenter)); - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindCover: EQS refinement query launched around %s"), - *Pawn->GetName(), *CoverCenter.ToString()); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(Pawn)) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindCover: EQS refinement query launched around %s"), + *Pawn->GetName(), *CoverCenter.ToString()); + } } void UPS_AI_Behavior_BTTask_FindCover::OnRefinementQueryFinished( diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp index d978f74..65701ca 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp @@ -5,6 +5,7 @@ #include "PS_AI_Behavior_PersonalityComponent.h" #include "PS_AI_Behavior_PersonalityProfile.h" #include "PS_AI_Behavior_TeamComponent.h" +#include "PS_AI_Behavior_Statics.h" #include "PS_AI_Behavior_Settings.h" #include "Perception/AISenseConfig_Sight.h" #include "Perception/AISenseConfig_Hearing.h" @@ -286,6 +287,11 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( TArray PerceivedActors; GetCurrentlyPerceivedActors(nullptr, PerceivedActors); // All senses at once + // Resolve debug flag once for all logs in this function + const AAIController* DebugAIC = Cast(GetOwner()); + const APawn* DebugPawn = DebugAIC ? DebugAIC->GetPawn() : nullptr; + const bool bDebugLog = UPS_AI_Behavior_Statics::IsDebugEnabled(DebugPawn); + // ─── Omniscient awareness for high-priority target types ──────── // Protectors (police, player) are always known if within sight radius, // even outside the perception cone. This ensures enemies prioritize @@ -325,10 +331,13 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( if (MappedType == TopPriority) { PerceivedActors.Add(CandidatePawn); - UE_LOG(LogPS_AI_Behavior, Verbose, - TEXT("[%s] Omniscient awareness: added '%s' (type=%d, dist=%.0f) — top priority target"), - *OwnerPawn->GetName(), *CandidatePawn->GetName(), - static_cast(CandidateType), Dist); + if (bDebugLog) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] Omniscient awareness: added '%s' (type=%d, dist=%.0f) — top priority target"), + *OwnerPawn->GetName(), *CandidatePawn->GetName(), + static_cast(CandidateType), Dist); + } } } } @@ -407,8 +416,11 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( // Allied teams (Civilian ↔ Protector) → allow gunfire through if (AIC->GetGenericTeamId().GetId() == GetActorTeamId(OwningPawn)) { - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] Target '%s': SKIPPED (same team 0x%02X)"), - *Owner->GetName(), *OwningPawn->GetName(), GetActorTeamId(OwningPawn)); + if (bDebugLog) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s': SKIPPED (same team 0x%02X)"), + *Owner->GetName(), *OwningPawn->GetName(), GetActorTeamId(OwningPawn)); + } continue; } @@ -430,9 +442,12 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( if (!bActorHasGunshot) { - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] Target '%s': SKIPPED (attitude=%d, not hostile, no gunshot, theirTeam=0x%02X, myTeam=0x%02X)"), - *Owner->GetName(), *OwningPawn->GetName(), static_cast(Attitude), - GetActorTeamId(OwningPawn), AIC->GetGenericTeamId().GetId()); + if (bDebugLog) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s': SKIPPED (attitude=%d, not hostile, no gunshot, theirTeam=0x%02X, myTeam=0x%02X)"), + *Owner->GetName(), *OwningPawn->GetName(), static_cast(Attitude), + GetActorTeamId(OwningPawn), AIC->GetGenericTeamId().GetId()); + } continue; // Not hostile, no gunshot — skip } } @@ -522,9 +537,12 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( { const FActorScore& Entry = Pair.Value; - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] Target '%s' (pawn='%s'): type=%d, hostile=%d, score=%.0f"), - *Owner->GetName(), *Entry.Actor->GetName(), *Pair.Key->GetName(), - static_cast(Entry.ActorType), Entry.bIsHostile ? 1 : 0, Entry.Score); + if (bDebugLog) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s' (pawn='%s'): type=%d, hostile=%d, score=%.0f"), + *Owner->GetName(), *Entry.Actor->GetName(), *Pair.Key->GetName(), + static_cast(Entry.ActorType), Entry.bIsHostile ? 1 : 0, Entry.Score); + } if (Entry.Score > BestScore) { 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 a8676a2..b503fcd 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 @@ -3,6 +3,7 @@ #include "PS_AI_Behavior_PersonalityComponent.h" #include "PS_AI_Behavior_Interface.h" #include "PS_AI_Behavior_PersonalityProfile.h" +#include "PS_AI_Behavior_Statics.h" #include "PS_AI_Behavior_AIController.h" #include "PS_AI_Behavior_SplineFollowerComponent.h" #include "PS_AI_Behavior_SplinePath.h" @@ -87,11 +88,14 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::EvaluateReaction() c const float EffectiveFleeThresh = FleeThresh * (0.5f + Courage * 0.5f) * (1.5f - Caution * 0.5f); const float EffectiveAttackThresh = AttackThresh * (1.5f - Aggressivity * 0.5f); - UE_LOG(LogPS_AI_Behavior, Log, - TEXT("[%s] EvaluateReaction: threat=%.2f, aggr=%.2f, courage=%.2f, caution=%.2f | attackThresh=%.2f, fleeThresh=%.2f, alertThresh=%.2f"), - GetOwner() ? *GetOwner()->GetName() : TEXT("?"), - PerceivedThreatLevel, Aggressivity, Courage, Caution, - EffectiveAttackThresh, EffectiveFleeThresh, AlertThresh); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(Cast(GetOwner()))) + { + UE_LOG(LogPS_AI_Behavior, Log, + TEXT("[%s] EvaluateReaction: threat=%.2f, aggr=%.2f, courage=%.2f, caution=%.2f | attackThresh=%.2f, fleeThresh=%.2f, alertThresh=%.2f"), + GetOwner() ? *GetOwner()->GetName() : TEXT("?"), + PerceivedThreatLevel, Aggressivity, Courage, Caution, + EffectiveAttackThresh, EffectiveFleeThresh, AlertThresh); + } // Decision cascade — with hysteresis to prevent state flickering. // Once in a state, require a larger threshold drop to leave it. @@ -231,11 +235,14 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::ApplyReaction() const EPS_AI_Behavior_State OldState = CurrentState; CurrentState = NewState; // Replicated → OnRep fires on clients - UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] State: %s -> %s (Threat: %.2f)"), - *GetOwner()->GetName(), - *UEnum::GetValueAsString(OldState), - *UEnum::GetValueAsString(NewState), - PerceivedThreatLevel); + if (UPS_AI_Behavior_Statics::IsDebugEnabled(Cast(GetOwner()))) + { + UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] State: %s -> %s (Threat: %.2f)"), + *GetOwner()->GetName(), + *UEnum::GetValueAsString(OldState), + *UEnum::GetValueAsString(NewState), + PerceivedThreatLevel); + } HandleStateChanged(OldState, NewState); } diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_Statics.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_Statics.cpp index 18a7a73..9c1955e 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_Statics.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_Statics.cpp @@ -1,10 +1,17 @@ // Copyright Asterion. All Rights Reserved. #include "PS_AI_Behavior_Statics.h" +#include "PS_AI_Behavior_PersonalityComponent.h" #include "Perception/AISense_Hearing.h" #include "CollisionQueryParams.h" #include "Engine/World.h" +static TAutoConsoleVariable CVarBehaviorDebug( + TEXT("ps.ai.Behavior.Debug"), + -1, + TEXT("Global debug override for PS_AI_Behavior. -1=use per-NPC bDebug property, 0=force off, 1=force on."), + ECVF_Default); + void UPS_AI_Behavior_Statics::ReportGunfire(UObject* WorldContext, FVector Location, AActor* Shooter, bool bIsEnemyFire, float Loudness, float MaxRange) { @@ -58,3 +65,16 @@ bool UPS_AI_Behavior_Statics::HasLineOfSight(const UWorld* World, const AActor* return !World->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_Visibility, Params); } + +bool UPS_AI_Behavior_Statics::IsDebugEnabled(const APawn* Pawn) +{ + // CVar override: 0=off, 1=on, -1=use property + const int32 CVar = CVarBehaviorDebug.GetValueOnGameThread(); + if (CVar == 0) return false; + if (CVar == 1) return true; + + // Fall through to per-NPC property + if (!Pawn) return false; + const auto* Personality = Pawn->FindComponentByClass(); + return Personality && Personality->bDebug; +} diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Statics.h b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Statics.h index e8641a2..f65686b 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Statics.h +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Public/PS_AI_Behavior_Statics.h @@ -53,4 +53,7 @@ public: */ static bool HasLineOfSight(const UWorld* World, const AActor* Source, const AActor* Target, float EyeHeightOffset = 150.0f); + + /** Check if debug is enabled for a given Pawn (checks CVar override first, then PersonalityComponent.bDebug). */ + static bool IsDebugEnabled(const APawn* Pawn); }; diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.dll b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.dll index e4d817f..363b703 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.dll and b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.dll differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.pdb index 4ead606..eefdf0c 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgent.pdb differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.dll b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.dll index 211aa16..db71779 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.dll and b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.dll differ diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.pdb b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.pdb index ffd5e89..8df8da0 100644 Binary files a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.pdb and b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Binaries/Win64/UnrealEditor-PS_AI_ConvAgentEditor.pdb differ