Replicated physics state not synchronized for sleeping bodies

Steps to Reproduce

Create an Actor with a Static Mesh Component (like a cube) as root, let’s call it Bob. Enable physics simulation in the component and replication in the actor ( bReplicates, bReplicateMovement and bAlwaysRelevant). Create a new default level, place Bob a bit above the ground and save it as TestLevel. Run the game and execute the command open TestLevel?listen. Wait for Bob to touch the ground and then sleep. Run another instance of the game and execute the command open 127.0.0.1.

Result: You’ll see Bob floating above the ground, never falling. Approaching it snaps it to the correct position.

Expected result: You should see Bob sleeping on the ground.

Probable Cause

While debugging, I noticed that while you see Bob floating, its internal PhysX body is actually in the right place. The client receives the correct physics state in AActor::PostNetReceivePhysicState() and applies it successfully. However, Bob’s sleeping state is also applied, never giving the Primitive Component the chance to synchronize to the PhysX body. You can see that approaching Bob with the DefaultPawn awakens it, letting it finally sync.

Possible Solution

Calling RootPrimComp->SyncComponentToRBPhysics() right after applying the received physics state in AActor::PostNetReceivePhysicState() (ActorReplication.cpp) fixes it.

I’ve just created a pull request regarding this issue (PR #3419).

Hey lucasncv,

Great, I was actually going to suggest that you do just that since you have a proposed fix.

Thanks