Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Cleanly resetting a ragdoll?

Discussion in 'Editor & General Support' started by bluescrn, Sep 26, 2013.

  1. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    Is it possible to cleanly reset a ragdoll? (all it's joints/rigidbodies?)

    I've got a character that switches between Mecanim-animation-controlled and ragdoll, by disabling the animator and switching the ragdoll bodies isKinematic on/off. Everything works fine the first time, with a nice transition from animation to ragdoll.

    Now I want to pool/recycle characters, as instantiation causes a big performance spike. But I'm having trouble resetting the ragdoll nodes ready to use again. It appears as either the joints are misbehaving when the ragdoll is enabled the second time, or the rigidbodies still have some velocity/force being applied - as some bones, particularly the characters arms, snap immediately to odd positions.

    It doesn't look 'completely broken', but there's clearly something not quite right.

    I'm currently zeroing the velocity/angularVelocity on the rigidbodies, but I'm not doing anything to the joints. Do these need resetting, and if so, how? (the node positions are obviously all updated by the Animator, so the ragdoll starts in a valid state - although different positions from the first time that it was enabled)

    Has anyone else encountered problems resetting ragdolls (or other other objects with physics joints?)
     
  2. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,169
    Yes, I have had this problem with rigidbodies, and resetting the velocity / angularvelocity didn't work for me. What DID work was setting the Rigidbody "IsKinematic" to true to turn it off, and then false to turn back on. I recall it not working if it happened all during the same update call (maybe something is triggered afterward to clean up). But it worked if it happened in subsequent frames.
     
    theANMATOR2b likes this.
  3. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    I've read that setting IsKinematic to true should zero the rigidBody's momentum - but all my bodies are being set back to IsKinematic whilst the character is animating (which works fine on 'recycled' character instances).

    Maybe it's something to do with the joints themselves? - can't see any obviously-resettable state on those, though...
     
  4. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    Strangely, this problem only seems to occur if the gameobject is turned off when the ragdoll components are enabled, then on again.

    If I never turn it off, I can repeatedly switch between ragdoll and animation mode without the problem. If I only turn it on and off when in animation mode, it's fine. But if I turn if off in ragdoll mode, then back on, the next time it switches the ragdoll mode, there appears to be unwanted motion (unwanted forces/velocities?/bad joint behaviour? - I'm still not sure exactly which)

    (I'm running a minimal test scene now, too - with all scripts removed except for my 'ragdoll toggler'...)
     
    theANMATOR2b likes this.
  5. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    Well, I found a workaround, but have absolutely no idea why it works/what causes the problem.

    Before turning off my character with SetActive(false), I turn the Animator back on for one frame, with the ragdoll bodies set to isKinematic=true, and the render meshes hidden, to hide the glitch that this would create.

    For some inexplicable reason, this prevents the problem from occuring. Very strange.
     
  6. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    The previous workaround didn't really work - it made things less-broken-looking, but wasn't actually a fix.

    I've now found out what's going on. It seems that disabling then re-enabling a character causes its joints to be re-initialized in an undesirable way, losing their 'home position'.

    If you set all the swing/twist limits to zero, the character should spring into his T-pose when the ragdoll is enabled, as the joints were set up relative to the T-pose in the editor. This works fine if the character has never been disabled/re-enabled.

    But if the character is turned off with SetActive(), then back on again, it doesn't snap to the T-pose next time the ragdoll is enabled. It appears tha it springs back to the position that the bones were in when the character was last disabled. The 'home position' of the joints has been changed, undesirably. (I think this is a bug in Unity, it doesn't seem very useful behaviour?)

    This explains why the ragdoll goes wrong/'floppy' - the twist/swing constraints are being enforced relative to an incorrect starting position.

    There seems to be a simple solution, though:

    On Awake(), store the local transform of all bones (which will be the original T-pose transforms)
    On OnDisable(), restore these transforms

    This seems to prevent the joints from being incorrectly reset/reinitialized.
     
    Sphynxe and theANMATOR2b like this.
  7. Kavorka

    Kavorka

    Joined:
    Sep 15, 2012
    Posts:
    247
    May I do some shameless advertising. For ragdolls that are not supposed to die immediately I have made this.



    Also good for situations where you want partial ragdoll effects. Maybe it could help you.

    Best wishes
    Patrik
     
    ekoops likes this.
  8. ekoops

    ekoops

    Joined:
    May 24, 2010
    Posts:
    74
    We tried this but did not work in out instance HOWEVER we did find the cause of our problems and the solution. It was due to the interpolation being set.

    So what has now worked is when we disable the character at the start of the level we set
    RigidbodyInterpolation.None;

    When we enable character
    RigidbodyInterpolation.Interpolate;

    Thankfully the problem is solved this way.
     
    theANMATOR2b likes this.
  9. mm1982

    mm1982

    Joined:
    Apr 28, 2015
    Posts:
    35
    Hi,

    these suggested workarounds don't seem to work for me. Anyone have any other insight into this problem? I am on unity 5.6

    Thanks for the help
     
  10. qiminixi

    qiminixi

    Joined:
    Jan 17, 2018
    Posts:
    1
    I found that after hide the character then show it in heirarchy, the ragdoll works right again.
    so, i do
    characterJoint.gameObject.SetActive(false);
    characterJoint.gameObject.SetActive(true);
    and set
    rigidbody.isKinematic = true;

    i solved the problem in this way. maybe joint is reset in OnEnable.
     
  11. ArshakKroyan

    ArshakKroyan

    Joined:
    Mar 4, 2015
    Posts:
    32
    This post helped me.
    I disabled the rigidbodies for some period of time (rigidbody.gameobject.SetActive(false)) and reenabled, so now my ragdoll is pretty stabile.