unity – Best practice for toggling between ragdoll and CharacterController


One feature of the game I’m working on is that if a character is hit with a certain amount of force, it will temporarily ragdoll, then get up off the ground after a small period of time. This character is moved by a CharacterController (CC) component. At the moment, I have the model as a child of an object with a CC component and movement script. My issue is that when the ragdoll is activated/animator is disabled, the model moves independently of the CC – if it ragdolls with some arbitrary force in any direction, the CC does not move with it (as you’d expect). This would be fine if the ragdoll wasn’t meant to be re-enabled, but it is. At this stage, the model teleports/moves to where the CC is, and it looks very weird.

I have tried a few different methods to synchronize the two:

  1. Decoupling the CC and model. Both objects are children of a shared parent, and I added them both to an PhysicsIgnoreLayer (for now – eventually if I go with this I’ll probably add all the ragdoll colliders to an array and ignore them individually). When the ragdoll state is enabled in the parent, the CC is disabled and the object is teleported to the root bone every frame. When the CC is enabled, the model is teleported to the CC object every frame. See here. The issue here is that setting the position means extra Update() calls and it lags behind the controller a little. Also, because the model isn’t a child of the controller, it doesn’t inherit the velocity of the controller, so it needs to be manually applied.
  2. Changing the parented GameObject at runtime. Depending on the state of the character, the CC/model will be parented to each other – if the CC is active, the model is set as its child and vice versa using SetParent. I couldn’t get this one working (the local position variable was a little confusing to me, but no configuration I tried worked for me).
  3. Conjoined CC and model. I placed the CC on the same object as the model. This isn’t really ideal for me because I want greater control over the rotation and presentation of the model. I couldn’t get this one working either – I don’t know how I could set the position of the CC without moving the whole thing.

Is there a more effective way of doing this? If so, what? I feel like I am greatly overcomplicating this. Any help would be great. In an ideal situation, I could have the model as a child of the controller (or behave that way) and move the CC when it is inactive without affecting the model position.