Replication of a physics ragdoll

I need to create a physics driven ragdoll that is simulated on a dedicated server and then replicated to the connected clients. The clients do not need to interact with the ragdoll in any direct way (you can think them as spectators).

Currently, the ragdoll is a blueprinted version of Owen from the Content Examples, with Owen wrapped into a single SkeletalMeshComponent (which is also the root component). The Blueprint itself is inherited from Actor.h.

If I check the Replicates and Replicate Movement checkboxes in the blueprint’s Defaults tab, the actor object itself and its root movement replicate fine (well, except that the latter seems to make the physics simulation extremely unstable). However, the pose of the ragdoll still becomes simulated separately on each client (they each see a different pose). What I have read from the forums, it seems that this is the intended default behavior of the engine: physics actors/components are not replicated by default.

Question 1: Is there any existing functionality in the engine to accomplish such a replication of a ragdoll pose, without having to copy the pose of the ragdoll manually on each frame?

Question 2: If there is no such functionality, then what would be the best way for replicating the pose manually (programming effort and performance-wise)? Is it possible to somehow take a “snapshot” of the ragdoll’s pose on the server, replicate that, and then apply it client-side? Or would it make any sense to replicate the transformation of each bone separately?

I am still rather new to the engine, so I’m a bit lost here. Any help is highly appreciated!

I am currently working with blueprints, but I am comfortable with C++ too (and what comes to performance, that is what the final solution probably needs to be anyways?).

In case that someone is trying to accomplish the same, this is how I ended up doing it for now.

On the server, store the pose: (pseudo)

SkeletalMeshComponent->SetSimulatePhysics( true );

void Tick()
{
    for( int bone = 0; bone < nBones; ++bone )
    {
        replicatedBuffer[bone] =
            SkeletalMeshComponent->Bodies[bone]->GetPxRigidDynamic()->getGlobalPose();
    }
    ...
}

On the client(s), apply the replicated pose: (pseudo)

// SkeletalMeshComponent->SetSimulatePhysics( false ); // cannot do this, see below

void Tick()
{
    for( int bone = 0; bone < nBones; ++bone )
    {
        SkeletalMeshComponent->Bodies[bone]->GetPxRigidDynamic()->
            setGlobalPose( replicatedBuffer[bone] );
    }
    ...
}

Edit: For a more concrete example, see http://answers.unrealengine.com/questions/123435/skeletal-mesh-kinematic-and-simulated-coordinate-s.html#answer-134553

In addition, enabling actor movement replication ensures that the movement of the entire actor becomes also replicated.

This works ok, except that the client-side skeletal mesh(es) cannot be switched to kinematic mode (SetSimulatePhysics( false )), due to this: Skeletal mesh: Kinematic and simulated coordinate systems mismatch (off by 90') - World Creation - Unreal Engine Forums . Thus, the client-side skeletal mesh(es) must not get in contact with actors that are simulated on client-side. I have not yet tried to do the replication on UE level (the current PhysX level was more convenient for me due to other reasons).

Is this expensive? I tried doing this in Unity once upon a time, and just 2-3 ragdolls being synced over the network caused complete unplayability of the game on clients due to lag.

I’m hoping UE will be better at it.

I had to ramp up network speed limits considerably: with the defaults, I got only something around 5 pose updates / sec. However, I am doing this only over LAN so it doesn’t really matter to me.

I am using Owen from Content examples, which has 22 physics bodies or so. At 60 fps, replicating the pose at each frame requires, I think, 22 * (3 + 4) * 4 * 60 = 40 kB / s (one 3d float vec and one 4d float quat per body per frame). So it might be well doable with a decent connection?

Over LAN and with one ragdoll, it works like a charm: no glitches, jitter or anything else! :slight_smile: But then again, I do not know whether there is some constant delay or not in the replicated pose stream, because I am not interacting with the ragdoll in any way on client-side (it is a spectator-like setup).

Reduced bandwidth usage via client-side prediction: There is the intriguing option to do the full pose update less frequently and fill in the gaps with client-side prediction. In principle, this should be straightforward: replicate the pose and the velocities from the server to the client(s), then on client-side, feed this data in as kinematic target data, and enable local physics simulation and physics blending → the client(s) should do a smooth blend between local simulation and the replicated pose stream!

However, I do not know how easy it is to use such a dynamic stream as a kinematic target in UE.

Also, when I tried to do something related, I stumbled on an issue with PhysX: if I set the pose and the velocity of a rigid body during the same tick, then PhysX did just ignore the velocity information and instead placed the body to full stop. Edit: For the record, this full stop thing turned out to be my fault!

If you or someone else knows how to implement this properly in UE, I would be interested in knowing about it! :slight_smile:

How did you increase the network speed limits? The code is working but it’s a slideshow for the character :S

Haha yes it was something like 1-5 fps for me with the defaults. :slight_smile:

Engine.ini, which you can override with Config/DefaultEngine.ini, has the following default values:

[/Script/Engine.Player]
ConfiguredInternetSpeed=10000
ConfiguredLanSpeed=20000

[/Script/OnlineSubsystemUtils.IpNetDriver]
MaxClientRate=15000
MaxInternetClientRate=10000

Increasing these should help!

I will try it out :slight_smile: Thanks ! Btw what values did you put in?

No prob. I practically disabled the limits with a value of 1000000000 or something, because I use this only over LAN and with a single ragdoll.

If you need to limit the bandwidth usage and decide to implement some sort of a client-side prediction system, so as to be able to sync the poses only every n:th frame and save some bits, then please let me know, I’m curious! :slight_smile:

(see also my answer to Acren, just before your first comment)

Hey i’ve tried it and it’s working at least on my pc with one client, i’ll have to test in the future on LAN :stuck_out_tongue: Right now i just need it to work in LAN, but if this feature goes to the final game i will have to do some client side prediction, probably lerping between the transforms.

There is no GetGlobalPose method after GetPxRigidDynamic. Is this outdated?

Also can we do this for just one bone and have the rest of the bones simulate physics if we just want the general bodies location to replicate but not have the rag doll physics be accurate?

If you use GetPxRigidDynamic_AssumesLocked() instead of GetPxRigidDynamic() you’ll have access to GlobalPose.