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,
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.
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!
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
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.
public bool Freeze
{
get => rigidbody.constraints == RigidbodyConstraints2D.FreezeAll;
set
{
rigidbody.constraints = value? RigidbodyConstraints2D.FreezeAll: RigidbodyConstraints2D.None;
rigidbody.AddForce(Vector2.zero);
}
}
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.
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.
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.
Using 2022.3 and WakeUp() neither adding torque works for rotation in 3D physics. Scenario is the same as OP, setting FreezeAll at some point and sometime later I am setting constraints to None. Adding force works, but adding torque does nothing. It looks correctly set in the inspector. After ticking and unticking some constraint in the inspector, torque starts to work. I will probably submit a bug report in the near future.
Edit: It seems that the inertiaTensor is not changed from zero to the original value when the constraints are set back to None. In the Inspector it looks like it does have a value but calling it in code gives a 0
As I wrote, adding force works correctly, just the torque is messed up. To my best knowledge, rotational constraints just set the appropriate coordinate of inertiaTensor to 0. When the constraint is unset, it should reset the inertiaTensor value to its original value. But this does not happen when setting constraints from a script, only when setting manually from inspector. After setting constraints to None from script, the inspector shows the original value of inertiaTensor, but when I Debug.Log it, it prints 0.
Already filed a bug report. For now I just set the inertiaTensor on the next line right after setting rigidbody constraints