The PlayerController sets an FRotator with ReplicatedUsing
to call a function that updates the FRotator when the player right clicks.
On Tick, the Character will rotate towards this FRotator. For testing purposes it is simply SetActorRotation() however it will use a lerp once I get it working, so it does need to run on Tick and not as a one-off.
Simply doing it this way would work fine, other than it doesn’t account for latency so if the player right clicks there will be a delay before the character reacts. To counteract this, I set the variable manually on the client so that they see it update on their end immediately.
However, this means that initially the client will rotate, then once the latency catches up it will repeat that rotation. For an example of what this actually looks like here’s a quick GIF. The things to keep in mind is that the FRotator variable is being set to an identical value on the server and all clients regardless of when it takes place.
Here is the code:
.h
UFUNCTION(Reliable, Server, WithValidation)
void ServerLookRotation(FRotator InRotation);
UPROPERTY(ReplicatedUsing = OnRep_LookRotation)
FRotator R_LookRotation;
UFUNCTION()
virtual void OnRep_LookRotation();
FRotator LookRotation;
GetLifetimeReplicatedProps - no difference without a condition
DOREPLIFETIME_CONDITION(APlayer_Proxy, R_LookRotation, COND_SimulatedOnly);
Replication from .cpp
bool APlayer_Proxy::ServerLookRotation_Validate(FRotator InRotation)
{
return true;
}
void APlayer_Proxy::ServerLookRotation_Implementation(FRotator InRotation)
{
//DoRep_LookRotation = !DoRep_LookRotation;
R_LookRotation = InRotation;
OnRep_LookRotation();
}
void APlayer_Proxy::OnRep_LookRotation()
{
//LookRotation = R_LookRotation;
if (Role != ROLE_AutonomousProxy)
{
LookRotation = R_LookRotation;
Print(FString("Doing!"), this);
}
}
Tick from .cpp
if (CR != nullptr)
{
CR->SetActorRotation(LookRotation);
if (Role != ROLE_SimulatedProxy)
{
Print(LookRotation, this);
}
}