I ran into the exact same issue. I’ve come to the conclusion that calling SetControlRotation() on the server does not replicate the change to the client. This leaves the two out-of-sync. I didn’t want to modify SetControlRotation() until I knew exactly how it was used throughout the code base, so I ended up creating my own function to force the client sync within my own PlayerController class. Here is the function definition:
/** Force the control rotation on client and server. */
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Pawn", meta = (Tooltip = "Set the control rotation."))
virtual void ForceControlRotation(const FRotator& NewRotation);
and here is the function’s body (from my ASDPlayerController class that derives from APlayerController):
void ASDPlayerController::ForceControlRotation(const FRotator& NewRotation)
{
if (!HasAuthority())
{
// Just call SetControlRotation() on the client
SetControlRotation(NewRotation);
return;
}
// On server
SetControlRotation(NewRotation);
// Force on client
ClientSetRotation(NewRotation);
}
In my Blueprint I then spawn my pawn/character, have the controller call Possess() with it, and then call my ForceControlRotation() to give both the pawn and controller the same rotation on the server and client.
I hope that helps out. If someone has a better solution that doesn’t require custom code, that would be great!
- Dave