Client Side Yaw Rotation only jittering with Default Pawn

UE 5.1.1

Hi,

I have an abnormal issue with multiplayer pawn sync between server and client.

The server has a pawn with a cinecamera in it, user can control it like a default pawn (with flying movement)

Client is either a character or a spectator and in the case of the spectator, its player controller get the view target from the server cinecamera.

So far, so good.

Except that on all clients, I have a severe jittering on the cinecamera pawn ONLY on the Yaw rotation at slow speed, every other axis is working perfectly fine and I just can’t understand why.

MovementComp is replicated, the server pawn with the cinecamera is replicated, every movement is working fine and is replicated, all but the Yaw rotation that is jittering.

Here is the code for the yaw and pitch rotation (as the end product is targeted to be used by filmmakers, Yaw is called Pan and Pitch is called Tilt)

Everything is working except Yaw, I tried to send first the vector so client can add controller yaw input on their side but it’s not solving the issue, then I send the entire rotation,not working either.

Tried also with Client instead of NetMulticast, with Reliable and Unreliable, I don’t have further ideas to solve this strange issue.

Thanks.

h file :

        UFUNCTION(Server,Unreliable)
	void RotatePanAndTilt(const FInputActionValue& Value);

	UFUNCTION(NetMulticast,Unreliable)
	void ClientRotateTilt(FRotator Rotator);

	UFUNCTION(NetMulticast,Unreliable)
	void ClientRotatePan(FRotator Rotator);

cpp file :

void ARusselCameraPawn::RotatePanAndTilt_Implementation(const FInputActionValue& Value)
{
	if(!HasAuthority()) return;
	
	const FVector2D MovementVector = Value.Get<FVector2D>();

	if(Controller == nullptr) return;

	if(!bIsPanLocked)
	{
		AddControllerYawInput(MovementVector.X * PanTurnBaseRate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);

		ClientRotatePan(GetActorRotation());
		
		OnCameraPanInputValueDelegate.Broadcast(MovementVector.X);
	}

	if(!bIsTiltLocked)
	{
		const float TiltInputValue=(- MovementVector.Y*TiltTurnBaseRate);

		const FRotator TiltDeltaRotation=UKismetMathLibrary::MakeRotator(0,TiltInputValue,0);
		
		PawnCamera->AddRelativeRotation(TiltDeltaRotation.Quaternion(),false);

		ClientRotateTilt(TiltDeltaRotation);

		OnCameraTiltInputValueDelegate.Broadcast(TiltInputValue);
	}
}

void ARusselCameraPawn::ClientRotateTilt_Implementation(FRotator Rotator)
{
	if(HasAuthority()) return;

	GEngine->AddOnScreenDebugMessage(-1, 60.f, FColor::Green, FString::Printf(TEXT("CLIENT ROTATE TILT !!")));

	PawnCamera->AddRelativeRotation(Rotator.Quaternion(),false);
}

void ARusselCameraPawn::ClientRotatePan_Implementation(FRotator Rotator)
{
	if(HasAuthority()) return;

	GEngine->AddOnScreenDebugMessage(-1, 60.f, FColor::Green, FString::Printf(TEXT("CLIENT ROTATE PAN !!")));

	//AddControllerYawInput(MovementVector.X * PanTurnBaseRate * BaseTurnRate * GetWorld()->GetDeltaSeconds() * CustomTimeDilation);
	SetActorRotation(Rotator);
}