Fix InteractionComponent ticking on server for remote client pawns

In a listen server, the server-side copy of a remote client's pawn also
has an InteractionComponent that ticks. This caused a race condition:
the server-side tick would start conversations using GetFirstPlayerController()
(= server's PC), setting NetConversatingPawn to the server's pawn instead
of the client's. The client's relay RPC arrived too late and was rejected
because bNetIsConversing was already true.

Fix: disable tick and skip mic creation in BeginPlay for non-locally-controlled
pawns. The client handles all interaction locally via relay RPCs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
j.foucher 2026-03-02 16:57:33 +01:00
parent 4d662ebada
commit 3c4389a43d

View File

@ -31,10 +31,24 @@ void UPS_AI_ConvAgent_InteractionComponent::BeginPlay()
{
Super::BeginPlay();
// Create mic capture component on the pawn.
AActor* Owner = GetOwner();
if (!Owner) return;
// Only run interaction logic on the locally controlled pawn.
// In a listen server, the server-side copy of a remote client's pawn also has
// this component, but it must NOT tick, evaluate agents, or create mic components.
// The client handles all interaction locally and routes through relay RPCs.
// Without this guard, the server-side tick would start conversations using
// GetFirstPlayerController() = server's PC, setting NetConversatingPawn to the
// wrong player (server instead of client).
APawn* OwnerPawn = Cast<APawn>(Owner);
if (OwnerPawn && !OwnerPawn->IsLocallyControlled())
{
SetComponentTickEnabled(false);
return;
}
// Create mic capture component on the pawn.
MicComponent = Owner->FindComponentByClass<UPS_AI_ConvAgent_MicrophoneCaptureComponent>();
if (!MicComponent)
{