I’m trying to replicate my actor rotation to all other clients which are connected in a multiplayer game. So far I’ve already achieved the implementation of a boolean called bIsAiming, following this awesome tutorial: A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums.
However I tried to get the replication of the rotation working in the same manner but keep stumbling across the problem that the rotation is only set on the calling client + the server. This means the server fails to tell all other clients to update the rotation of said actor accordingly. I’m a bit puzzled at the moment. I already tried to replicate an FRotator and SetActorRotation in the EveryTick method but this wasn’t successful either.
Here is my code example, perhaps someone can point me in the right direction
BaseCharacter.h
// gets the rotation needed to aim at the crosshair
FRotator getRotationToCrosshair();
// rotates the actor
void SetRotation(FRotator rot);
UFUNCTION(Server, Reliable, WithValidation)
void ServerSetRotation(FRotator rot);
void ServerSetRotation_Implementation(FRotator rot);
bool ServerSetRotation_Validate(FRotator rot);
BaseCharacter.cpp
FRotator ABaseCharacter::getRotationToCrosshair()
{
//set Rotation towards crosshair
FRotator camYawn = FRotator(0, FollowCamera->GetComponentRotation().Yaw, 0);
FRotator charYawn = FRotator(0, GetControlRotation().Yaw, 0);
FRotator charRotation = FMath::RInterpTo(camYawn, charYawn, 400, 0.1);
return charRotation;
}
void ABaseCharacter::SetRotation(FRotator rot)
{
SetActorRotation(rot);
if (Role < ROLE_Authority)
{
ServerSetRotation(rot);
}
}
//////////////////////////////////////////////////////
// REPLICATION
/////////////////////////////////////////////////////
void ABaseCharacter::ServerSetRotation_Implementation(FRotator rot)
{
SetRotation(rot);
}
bool ABaseCharacter::ServerSetRotation_Validate(FRotator rot)
{
return true;
}
void ABaseCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// Value is already updated locally, skip in replication step
DOREPLIFETIME_CONDITION(ABaseCharacter, bIsAiming, COND_SkipOwner);
//DOREPLIFETIME_CONDITION(ABaseCharacter, rotation, COND_SkipOwner);
the setRotation method is called here in the .cpp
void ABaseCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
if (IsAiming())
{
ZoomIn();
}
else
{
ZoomOut();
}
}
void ABaseCharacter::ZoomIn()
{
//to-do: toggle crosshair
if (!bIsSprinting && GetCharacterMovement()->IsMovingOnGround())
{
if (!bIsZooming)
{
//switch to over the shoulder view
FollowCamera->SetWorldLocation(ShoulderCameraPosition->GetComponentLocation(), true);
}
bIsZooming = true;
SetRotation(getRotationToCrosshair());
}
}
Thanks in advance!
~Theo
P.S: Is it possible that the characterMovementComponent already handels the replication of the bIsCrouched and if a character is in the air? I didn’t need to implement methods for jumping and crouching as they were perfectly working in a multiplayer setup.