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

RigidBody Constraints not Unfreezing

Discussion in 'Scripting' started by Mashimaro7, Jul 22, 2020.

  1. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    I'm very confused at this, I have a script that unfreezes the rigidbody constraints when my characters die, but for some strange reason, it seems to be unfreezing them in the inspector but not actually unfreezing them.
    This is my script,
    Code (CSharp):
    1.     void Death()
    2.     {
    3.         deathRoutine = true;
    4.         rb.constraints = RigidbodyConstraints.None;
    5.         animator.SetBool("isDead", true);
    6.         Destroy(GetComponent<NavMeshAgent>());
    7.         rb.angularDrag = -0.5f;
    8.         rb.AddForce(0, 30, 0);
    9.     }
    10.     void Update()
    11.     {
    12.         if(health <= 0)
    13.             {
    14.             isDead = true;
    15.             health = 0;
    16.             }
    17.         if(isDead && !deathRoutine)
    18.             {
    19.             Death();  
    20.             }
    21.     }
    I have the constraints being removed before everything else, but it doesn't seem to work. The strangest part is, if I manually untick the constraints and then play the Death() method, it falls down properly... I even tested it by adding 10 torque to all axises at the very end of the Death() method, it rotated on the Y axis(the only one I don't have frozen) but not on any other axis.

    Thanks in advance.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,714
    Is that animator driving rotation? If it is, then the animator will keep the object upright.

    If it is not, then perhaps try just Destroy()ing the Rigidbody when the death happens and see if any other code complains, and perhaps you will discover that other code is actually doing something you don't want it to do, such as reapplying constraints. :)

    Line 7 above also seems suspect... I don't think you can set negative angular drag. Try setting it to zero. It is possible this is messing with something in the physics simulation. Try one thing at a time though!
     
    Mashimaro7 likes this.
  3. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    I tried adding "Destroy(rb);", gets rid of the rb, but no errors. It's the weirdest thing, I can see the restraints disappearing in the inspector. But he doesn't fall, yet if I manually disable them, and then click "isDead" he falls over just fine...

    Edit: I think I fixed it, I'm still confused though haha, I changed it from a method back to a coroutine, added a very miniscule delay before adding force...I think it's a bug, because it should've still fallen over even without the force haha
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,714
    Try making your Death() function into a coroutine, then doing these steps:

    1. do everything except the animation change

    2. do a
    yield return new WaitForFixedUpdate();


    3. set "IsDead" true for the animator.
     
    Mashimaro7 likes this.
  5. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    723
    Thanks, still not sure what was wrong, but I fixed it. I just had that animator code there for a placeholder, there's still no death animation haha.
     
  6. Siliko

    Siliko

    Joined:
    Sep 7, 2020
    Posts:
    8
    Exactly same problem here
     
  7. Siliko

    Siliko

    Joined:
    Sep 7, 2020
    Posts:
    8
    Ok, i just add a little force Impulse to get the guy moving and the fall followed
     
    Mashimaro7 likes this.
  8. Issun

    Issun

    Joined:
    Nov 7, 2013
    Posts:
    17
    Same problem here, changing constraints from
    RigidbodyConstraints2D.FreezeAll
    to
    RigidbodyConstraints2D.None
    my dude just floated still in the air, then checking one of the boxes again in the editor caused him to fall. Almost like it doesn't do anything until interacted with.

    As a scuffed sort of fix, I added this
    rigidbody.AddForce(Vector2.zero);
    after setting constraints to none.

    Code (CSharp):
    1.  
    2. public bool Freeze
    3. {
    4.     get => rigidbody.constraints == RigidbodyConstraints2D.FreezeAll;
    5.     set
    6.     {
    7.         rigidbody.constraints = value? RigidbodyConstraints2D.FreezeAll: RigidbodyConstraints2D.None;
    8.         rigidbody.AddForce(Vector2.zero);
    9.     }
    10. }
    11.  
    Adding zero force seems to make the rigidbody "wakeup" and then fall. Bit dodgy but does the job and shouldn't have any side effects.
     
    Mashimaro7 likes this.
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,513
    If you want to explicitly wake a body, simply use Rigidbody2D.WakeUp()

    Constraints are a call into Box2D and it doesn't wake it but we could obviously change that to do so. Waking a body on any kind of change isn't always a good thing so for many calls it's not done automatically. Know that waking a body will also wake everything it's in contact with so it's used carefully.

    The OP is obviously about PhysX but it would seem to not wake either.
     
    Bunny83, Issun and Mashimaro7 like this.
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,525
    Right. Some seem to be unaware of the concept of sleeping. I recommend reading the physics overview. At the bottom is the section "Rigidbody optimization" which explains that concept.

    Also you can use the IsSleeping method to query the current state and use the methods WakeUp and Sleep to force-change the sleep state. Though a rigidbody still falls asleep or wakes up automatically when it hits the sleeping threshold or when another rigidbody collides with it or when some other force is applied to it.