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 7aa640b..6a851f4 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 @@ -74,7 +74,7 @@ void UPS_AI_Behavior_BTService_UpdateThreat::TickNode( BB->SetValueAsFloat(PS_AI_Behavior_BB::ThreatLevel, FinalThreat); - UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] UpdateThreat: raw=%.2f, stored=%.2f, final=%.2f"), + UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] UpdateThreat: raw=%.2f, stored=%.2f, final=%.2f"), *AIC->GetName(), RawThreat, StoredThreat, FinalThreat); // ─── Update threat actor and location with LOS tracking ───────── 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 521c268..c27b2d2 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 @@ -32,7 +32,7 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( } // Debug: log state on entry - UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] FindAndFollowSpline: bIsFollowing=%d CurrentSpline=%s"), + 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")); @@ -59,7 +59,7 @@ 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, Log, + 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); @@ -73,7 +73,7 @@ EBTNodeResult::Type UPS_AI_Behavior_BTTask_FindAndFollowSpline::ExecuteTask( /*bUsePathfinding=*/true, /*bProjectDestinationToNavigation=*/true, /*bCanStrafe=*/false); - UE_LOG(LogPS_AI_Behavior, Log, + UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindAndFollowSpline: MoveToLocation result=%d (0=Failed, 1=AlreadyAtGoal, 2=RequestSuccessful)"), *AIC->GetName(), (int32)Result); @@ -98,7 +98,7 @@ 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, Log, + UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] FindAndFollowSpline: close enough, StartFollowingAtDistance(dist=%.0f, fwd=%d)"), *AIC->GetName(), ClosestDist, (int32)bForward); Follower->StartFollowingAtDistance(Follower->CurrentSpline, ClosestDist, bForward); 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 fac5577..72d5694 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 @@ -215,7 +215,7 @@ 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, Log, + 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()); 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 a841d2a..d978f74 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 @@ -325,7 +325,7 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( if (MappedType == TopPriority) { PerceivedActors.Add(CandidatePawn); - UE_LOG(LogPS_AI_Behavior, Log, + 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); @@ -407,7 +407,7 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( // Allied teams (Civilian ↔ Protector) → allow gunfire through if (AIC->GetGenericTeamId().GetId() == GetActorTeamId(OwningPawn)) { - UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s': SKIPPED (same team 0x%02X)"), + UE_LOG(LogPS_AI_Behavior, Verbose, TEXT("[%s] Target '%s': SKIPPED (same team 0x%02X)"), *Owner->GetName(), *OwningPawn->GetName(), GetActorTeamId(OwningPawn)); continue; } @@ -430,7 +430,7 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( if (!bActorHasGunshot) { - UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s': SKIPPED (attitude=%d, not hostile, no gunshot, theirTeam=0x%02X, myTeam=0x%02X)"), + 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()); continue; // Not hostile, no gunshot — skip @@ -522,7 +522,7 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( { const FActorScore& Entry = Pair.Value; - UE_LOG(LogPS_AI_Behavior, Log, TEXT("[%s] Target '%s' (pawn='%s'): type=%d, hostile=%d, score=%.0f"), + 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); diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_BodyExpressionComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_BodyExpressionComponent.cpp index 23c9c3c..977e784 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_BodyExpressionComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_BodyExpressionComponent.cpp @@ -232,18 +232,17 @@ void UPS_AI_ConvAgent_BodyExpressionComponent::PickAndSwitchAnim() void UPS_AI_ConvAgent_BodyExpressionComponent::OnConversationConnected( const FPS_AI_ConvAgent_ConversationInfo_ElevenLabs& Info) { - bActive = true; + // Don't activate yet — wait for the agent to actually speak (OnSpeakingStarted). + // This prevents body expressions from playing while the NPC is still walking + // and the user hasn't said anything yet. bIsSpeaking = false; LastEventName = TEXT("Connected"); LastEventWorldTime = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f; - // Start with an idle anim - PickAndSwitchAnim(); - if (bDebug) { UE_LOG(LogPS_AI_ConvAgent_BodyExpr, Log, - TEXT("Conversation connected — body expression activating (idle).")); + TEXT("Conversation connected — waiting for agent speech to activate body expressions.")); } } @@ -268,6 +267,12 @@ void UPS_AI_ConvAgent_BodyExpressionComponent::OnConversationDisconnected( void UPS_AI_ConvAgent_BodyExpressionComponent::OnSpeakingStarted() { + // Activate on first speech if not already active (deferred from OnConversationConnected) + if (!bActive) + { + bActive = true; + } + bIsSpeaking = true; LastEventName = TEXT("SpeakStart"); LastEventWorldTime = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f; @@ -278,7 +283,7 @@ void UPS_AI_ConvAgent_BodyExpressionComponent::OnSpeakingStarted() if (bDebug) { UE_LOG(LogPS_AI_ConvAgent_BodyExpr, Log, - TEXT("Agent started speaking — switching to speaking body anim.")); + TEXT("Agent started speaking — body expression activating + speaking anim.")); } }