[BUG] Character Rotation Replication Issue

I am seeing a bug when rotation of a character is replicated, specifically it’s roll that is causing problems.

rotation works fine on server or autonomous clients, but on simulated clients rotation seems to be offset.

I’ve taken a look at ReplicatedMovement being received on client, and location/correction is correct.

It appears that only character visual is incorrect, actual capsule appears to be in right position/rotation.
My suspicion is that this is caused by mesh component (which is a child of capsule) not rotating correctly on client (Like samples, my mesh location and rotation has been tweaked to make it line up with capsule).
Could this be on rendering side of things?

I’ve also confirmed that this still occurs with 4.2.

This is easy to achieve with Third Person Code Template:

// Hook to input key
void AThirdCharacter::RotateProblemStart()
{
	ServerDoRotate(); // Tell  server to rotate
	SetActorRotation(FRotator(0, 0, 90)); // Do it locally on  controlling client
}

// Client -> Server RPC
void AThirdCharacter::ServerDoRotate_Implementation()
{
	SetActorRotation(FRotator(0, 0, 90)); // Rotate on server, this will replicate to remote clients
}

Server/Controller:

Client:

Collision:

Hi,

Sorry, but that isn’t correct.
Location and Rotation for characters is replicated, you can clearly see that’s case as rotation has taken effect on client.

You can take a look at ACharacter::PostNetReceiveLocation, that is running correctly on my client and has correct Location/Rotation.

A “Server” function executes only on server. It is not replicated serve → other clients.

You have two options:

  • Create a UFUNCTION(NetMulticast) void BroadcastNewRotation(FRotator NewRot). BroadcastNewRotation_Implementation will do rotation. Call BroadcastNewRotation() from your ServerDoRotate() (NetMulticast functions can only be called by server). Note that NetMulticast functions also run on server itself, as well as all clients.

  • Create a FRotator MyRot that is RepNotify: UPROPERTY(ReplicatedUsing=OnRep_MyRot), add MyRot to GetLifetimeReplicatedProps() function, and create a OnRep_MyRot function that modifies rotation. See ShooterGame for examples – plenty of them there, for example, variable BurstCounter in AShooterWeapon.

I’m having same problem. I’m curious if this is a known engine bug and what I can do to fix it? I’d rather not have to debug way down into engine to try to find cause of this issue. Maybe there is some sort of work around to this problem?

No one has any suggestions to help?
This is blocking implementation of a major feature in our game. Looks like Didek is also effected.

Hey Joeh,

I am looking into this issue for you, and will update you as soon as I can. Thanks for your patience so far!

Thanks !

Don’t suppose you have had any luck with this?

I can confirm this is still a problem with released version of 4.2. , have you made any progress reproducing this?

Hey Joeh,

Sorry for delay in response. I’ve checked in with developers on this issue and can confirm that they are looking into it. I hope to hear something soon, and will let you know as soon as I do. Thanks again for your patience!

Hi,

I suspect that assumptions about a vertically oriented capsule in mesh offset code is messing with mesh translation. It appears that capsule itself is oriented correctly (based on “show collision” result you posted, though it would be nice to confirm that with a shot on both sides).

Try overriding UCharacterMovementComponent::SmoothClientPosition and SmoothCorrection to do nothing in your own component and see if that makes a difference. That is only run on client and is only thing I can think of that is messing with offset on client and not server.

It looks like those smoothing methods are indeed culprit.
I’m not sure if this is a candidate for being resolved on engine side, or if it makes most sense for us to override them and have different behavior for our custom movement mode.

What are your thoughts?

Glad you were able to work around it!

I think this is an issue with engine code only because we assume a vertical capsule orientation. Down road we were looking at possibly removing this assumption and adding support for arbitrary Up vectors, at which point we’ll have to fix this.

There is one line of code in SmoothClientPosition() that zeros MeshTranslationOffset.Z if walking, I wonder if just removing that line in your own version would fix issue. If so I would recommend only doing that when walking and orientation is vertical. Character itself also does some things explicitly with Z in crouch methods, which might be an issue later.

I don’t think it can be zeroing Z, because IsMovingOnGround requires you to be in Walking movement mode. Nothing else in either of those methods jumps out at me as being a problem.

I’ll dig into a little more and see if I can find exact culprit.

Just hitting this myself. Wondering if you found a solution? :smiley:

See rcdarcey’s comment below, hopefully that is helpful.

Lol sorry. I was confused by why thread was split. Glad it’s working!

I found a very simple solution for this! At least for characters in MOVE_Flying mode. Not sure it’ll work for MOVE_Walking, but worth a try.

Anyway, it seems like all I needed to do was set bUseControllerRotationRoll to true on pawn and…BOOM. No more server network smoothing fighting roll rotation :smiley:

yahp…answered my own question here :wink: