Get Rigidbodies to Sleep Faster

I’m colorizing all the rigidbodies that are awake in my scene so it’s easier to tell when they go to sleep, and currently, they’re taking too long. I can afford to be extremely lenient with accuracy, so I don’t mind if they stop simulating before fully settled.

Unfortunately, no amount of tweaking Sleep Velocity and Sleep Angular Velocity seems to work. I’ve incrementally cranked them up to 10000 from the default 0.14, and also tested 0.014 just to make sure I didn’t misunderstand how those values are supposed to work.

I’ve also verified that the active rigidbodies are indeed getting set with the right sleep velocities.

As a final note, they seem to be deactivating in large groups/piles, which makes sense that the simulation would be recursive. I’d still like the piles to deactivate faster though.

Whelp, I was hoping to leverage the built-in sleep functionality, but I guess the manual approach is more flexible and easier to control.

This is my test for if the rigidbody is ready to go to sleep, as mentioned in my reply to robertbu:

if (grounded && aliveTime >= minimumAliveTime && rigidbody.velocity.sqrMagnitude < sleepVelocity)

3 important notes:

  1. If you don’t test whether the rigidbody is grounded (that is, colliding with something else) it’s very common for a rigidbody flying near-vertical to freeze in mid-air, where velocity can come very close to 0 at the peak of its arc.
  2. If you want a rigidbody to instantiate without an initial velocity (i.e. to let gravity naturally pull it down) you’ll need to impose a minimum alive time before testing its velocity, otherwise it’ll instantly go to sleep before it ever picks up enough speed to exceed the sleep threshold.
  3. Use velocity.sqrMagnitude because it avoids the expensive sqrt step of velocity.magnitude, but still works perfectly fine for this situation if you adjust the sleep velocity.

To test whether it’s grounded, just use the OnCollision methods Unity provides:

`
void OnCollisionEnter ()
{
grounded = true;
}

void OnCollisionStay ()
{
grounded = true;
}

void OnCollisionExit ()
{
grounded = false;
}
`

There’s a chance with the above code that a rigidbody could hit a ceiling and freeze from satisfying the OnCollision state and velocity being less than the sleep threshold if it hits head-on. You might have to get a little fancier with your tests if this is a possibility in your game.

Doing the alive time is pretty straightforward:

`
public void Activate ()
{
if (!rigidbody)
{
aliveTime = 0f;
}
}

void FixedUpdate ()
{
if (rigidbody)
{
aliveTime += Time.deltaTime;
}
}

`

I’ve found a minimum alive time of 1 second and a sleep velocity of 0.1 work well for aggressively putting rigidbodies to sleep without sacrificing a lot of quality.