|
|
|
|
@@ -225,6 +225,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::StartConversation()
|
|
|
|
|
APlayerController* PC = GetWorld()->GetFirstPlayerController();
|
|
|
|
|
bNetIsConversing = true;
|
|
|
|
|
NetConversatingPlayer = PC;
|
|
|
|
|
NetConversatingPawn = PC ? PC->GetPawn() : nullptr;
|
|
|
|
|
}
|
|
|
|
|
StartConversation_Internal();
|
|
|
|
|
}
|
|
|
|
|
@@ -298,6 +299,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::EndConversation()
|
|
|
|
|
// Reset replicated state so other players can talk to this NPC.
|
|
|
|
|
bNetIsConversing = false;
|
|
|
|
|
NetConversatingPlayer = nullptr;
|
|
|
|
|
NetConversatingPawn = nullptr;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
@@ -608,6 +610,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::HandleDisconnected(int32 StatusCode,
|
|
|
|
|
{
|
|
|
|
|
bNetIsConversing = false;
|
|
|
|
|
NetConversatingPlayer = nullptr;
|
|
|
|
|
NetConversatingPawn = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OnAgentDisconnected.Broadcast(StatusCode, Reason);
|
|
|
|
|
@@ -1032,7 +1035,12 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::EnqueueAgentAudio(const TArray<uint8>
|
|
|
|
|
else if (bPreBuffering)
|
|
|
|
|
{
|
|
|
|
|
// Second (or later) audio chunk arrived during pre-buffer period.
|
|
|
|
|
// We now have both chunks buffered — start playback immediately.
|
|
|
|
|
// On Authority: this means a genuine second TTS chunk arrived from the
|
|
|
|
|
// WebSocket, so we have enough data buffered — start playback immediately.
|
|
|
|
|
// On Clients: sub-chunks from network splitting arrive nearly simultaneously,
|
|
|
|
|
// which would defeat the pre-buffer. Let the timer in TickComponent handle it.
|
|
|
|
|
if (GetOwnerRole() == ROLE_Authority)
|
|
|
|
|
{
|
|
|
|
|
bPreBuffering = false;
|
|
|
|
|
if (bDebug)
|
|
|
|
|
{
|
|
|
|
|
@@ -1047,6 +1055,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::EnqueueAgentAudio(const TArray<uint8>
|
|
|
|
|
{
|
|
|
|
|
AudioPlaybackComponent->Play();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SilentTickCount = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -1195,6 +1204,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::GetLifetimeReplicatedProps(
|
|
|
|
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
|
|
|
DOREPLIFETIME(UPS_AI_ConvAgent_ElevenLabsComponent, bNetIsConversing);
|
|
|
|
|
DOREPLIFETIME(UPS_AI_ConvAgent_ElevenLabsComponent, NetConversatingPlayer);
|
|
|
|
|
DOREPLIFETIME(UPS_AI_ConvAgent_ElevenLabsComponent, NetConversatingPawn);
|
|
|
|
|
DOREPLIFETIME(UPS_AI_ConvAgent_ElevenLabsComponent, CurrentEmotion);
|
|
|
|
|
DOREPLIFETIME(UPS_AI_ConvAgent_ElevenLabsComponent, CurrentEmotionIntensity);
|
|
|
|
|
}
|
|
|
|
|
@@ -1210,15 +1220,15 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::OnRep_ConversationState()
|
|
|
|
|
// on the local pawn, but remote clients never run that code path.
|
|
|
|
|
if (UPS_AI_ConvAgent_PostureComponent* Posture = Owner->FindComponentByClass<UPS_AI_ConvAgent_PostureComponent>())
|
|
|
|
|
{
|
|
|
|
|
if (bNetIsConversing && NetConversatingPlayer)
|
|
|
|
|
// Use NetConversatingPawn (replicated to ALL clients) instead of
|
|
|
|
|
// NetConversatingPlayer->GetPawn() — PlayerControllers are only
|
|
|
|
|
// replicated to their owning client (bOnlyRelevantToOwner=true).
|
|
|
|
|
if (bNetIsConversing && NetConversatingPawn)
|
|
|
|
|
{
|
|
|
|
|
if (APawn* PlayerPawn = NetConversatingPlayer->GetPawn())
|
|
|
|
|
{
|
|
|
|
|
Posture->TargetActor = PlayerPawn;
|
|
|
|
|
Posture->TargetActor = NetConversatingPawn;
|
|
|
|
|
Posture->ResetBodyTarget();
|
|
|
|
|
Posture->bEnableBodyTracking = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Posture->TargetActor = nullptr;
|
|
|
|
|
@@ -1271,6 +1281,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::ServerRequestConversation_Implementat
|
|
|
|
|
|
|
|
|
|
bNetIsConversing = true;
|
|
|
|
|
NetConversatingPlayer = RequestingPlayer;
|
|
|
|
|
NetConversatingPawn = RequestingPlayer ? RequestingPlayer->GetPawn() : nullptr;
|
|
|
|
|
|
|
|
|
|
StartConversation_Internal();
|
|
|
|
|
}
|
|
|
|
|
@@ -1289,6 +1300,7 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::ServerReleaseConversation_Implementat
|
|
|
|
|
|
|
|
|
|
bNetIsConversing = false;
|
|
|
|
|
NetConversatingPlayer = nullptr;
|
|
|
|
|
NetConversatingPawn = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UPS_AI_ConvAgent_ElevenLabsComponent::ServerSendMicAudio_Implementation(
|
|
|
|
|
|