CharacterMesh component location reverting back to default location on non-owning clients

Working in Blueprints with a Character blueprint, I’m having difficulty updating the location of the Mesh(CharacterMesh)(Inherited) component.

I’m trying to implement ducking functionality and my flow looks like this: button press → “update” locally → call server → server calls all clients → every client except the one that owns the character “updates” their version of the character. The “update” consists of doing the following things: modifying the size of the CapsuleComponent by setting the CapsuleHalfHeight, modifying the location of the mesh (which is a child component of the CapsuleComponent), and modifying the position of the camera (which is a child component of the mesh). When running in PIE with 2 clients and a “dedicated server,” I’m able to see the CapsuleComponent shrink when the other player ducks. The camera also correctly changes location; however, the mesh does not.

I think in reality the mesh actually does change location, but then as gravity causes the character to fall, it reverts back to it’s default location. I sort of confirmed this by adding some additional functionality at the end of the multicast call from the server. I put in a 2s delay and then, once again, ran the “update” to update the size of the capsule, the location of the mesh, and the location of the camera. When doing this, I observe (through the other client’s PIE) that the location is correctly set after the 2s delay; however, if the character moves in the slightest, the location of the mesh instantly reverts back to it’s default location.

What’s going on here? Is there something with Actor ownership that I don’t understand? Thanks in advance.

I solved this, but I figured I’d post my answer in case this helps out anyone in the future. The reason the mesh’s offset (i.e. the mesh component’s location) is not persisting is due to the way the networking interpolating is happening. In short, for actors of type Character, the mesh component’s location is cached at the beginning of gameplay. It is this cached location that is used as the target location to interpolate back to when a server sends a positional update back to the client. Unfortunately, it completely ignores whatever dynamic, run-time modifications are made to the mesh component’s location.

The folks at UE have already solved this for us - there is a function in the Character class called CacheInitialMeshOffset and even better…it is Blueprint callable. Setting the mesh component’s location via this function modifies the cached position (and thus the location that the mesh is always slowly heading towards). Problem solved :).

One last thing to note, if the Character is the actual Actor that the local player is playing, then the Character is not actually using the interpolation logic to slowly move to it’s “correct” position. This is because the player defines the true position the Actor is supposed to be in. For this specific case, simply set the relative location of the mesh component like you would normally.

2 Likes

Thank you so much for posting how you solved it! I was having the exact same issue and this was it!