TransWikia.com

Unity 4 - Some Rigidbodies Won't Fall Asleep

Game Development Asked by Ryan Berserkguard Nørby on January 3, 2021

I’m having this problem in the free edition of Unity 4.1 where rigidbodies aren’t falling asleep (and yes, I’ve tried playing with the sleepVelocity and sleepAngularVelocity values!). I’ve read the docs at http://docs.unity3d.com/Documentation/Components/RigidbodySleeping.html but cannot figure out the problem.

Here is a screenshot demonstrating my problem:
Rigidbody Sleep Diagram http://uberlethal.com/random/rigidbody_sleeping.png

I wrote a script that is attached to the rigidbodies in question, which sets the material color to red if the rigidbody is currently asleep or green if it is awake. The screenshot was taken when all objects were at rest. As you can see, not all of the gameobjects are sleeping. Each piece of debris you see on screen is its own gameobject with a rigidbody and collider.

The Unity docs I linked to above state the following:

Rigidbodies automatically wake up when:

  • another rigidbody collides with the sleeping rigidbody
  • when adding forces.

Perhaps some clarification on the above might help solve this issue: If two rigidbodies are touching when they fall to "rest", will they never stay asleep? Put another way, would they just keep interrupting each other’s sleep? As for the "adding forces" part, do sleeping rigidbodies awake only when forces are added directly to them, or when any force is added to any object (this is important because I am using a rigidbody character controller which moves via AddForce() calls)

I have tried manually sleeping objects myself with undesired results. What usually happens when I do this is that some objects will remain suspended in the air.

Let me know if you need other details – I have tried a great deal of things.

5 Answers

You can try looking at this.GetComponent<Rigidbody>().sleepThreshold = 0.0f;

sleepThreshold is what makes one of the variables of falling asleep

Rigidbody.sleepThreshold not giving a lot of information more then that...

Answered by amitklein on January 3, 2021

For the record, I had this same problem suddenly pop up where it hadn't before.

After lots of troubleshooting, I discovered it was a physics2D collider error. I had mistakenly set a dynamic collider object in conflict with a kinematic (floor) object in a way that couldn't resolve itself when the game started. This kept any objects that contacted that same floor from being able to go to sleep, for some reason.

Hope it saves somebody a bit of time! (Unity 2017.3, Mac)

Answered by Logan Lux on January 3, 2021

I run into the same problem today and just in case someone runs into the same trouble, another temporary workaround could be using a coroutine like this:

using a wait time.

    private IEnumerator ResumeRigidbody(GameObject someObj, float waitTime) {
        var startingTime = Time.time;
        var startingPos = someObj.transform.position;

        //dummy way of preventing gravity, rigidbody functions do not seem to work
        while(Time.time - startingTime < waitTime) {
            someObj.transform.position = startingPos;
            yield return new WaitForFixedUpdate();
        }
    }

    StartCoroutine(ResumeRigidbody(gameObject, 2f));

or a boolean.

    private IEnumerator ResumeRigidbody(GameObject someObj) {
        var startingPos = someObj.transform.position;
        WaitingIsOver = false;
        //dummy way of preventing gravity, rigidbody functions do not seem to work
        while(!WaitingIsOver) {
            someObj.transform.position = startingPos;
            yield return new WaitForFixedUpdate();
        }
    }

    StartCoroutine(ResumeRigidbody(gameObject));

    //and after some event
    WaitingIsOver = true;

Answered by Angelos Kyriakopoulos on January 3, 2021

In the end I solved it by manually figuring out when to destroy the rigidbodies and colliders. I created a box collider trigger that goes from the floor to the player's knees. When an object breaks (and the GameObject is replaced with the broken version), there is a script that checks every 5 seconds to see if any of its rigidbody children are fully enclosed by the trigger. The script then destroys any rigidbodies and colliders that meet this criteria and stops polling.

It feels a bit hackish, and only works for my specific use case, but it gets the job done. Even after breaking several hundred objects in rapid succession, the physics isn't getting overloaded like it was before.

If anyone thinks of a more elegant solution, please let me know!

Answered by Ryan Berserkguard Nørby on January 3, 2021

Rigidbodies awake when any force is applied to them. If you had a pool game and all the balls are sleeping and you would hit them with another ball, they would all wake up.

I guess there is some minimal jittering going on that keeps your rigidbodies alive. There are a lot of parameters that can have an impact on this, but personally I would first and foremost look into these:

  • Use a Physics Material for your colliders and start with high friction values and no bounciness.
  • Increase the Drag and AngularDrag values of your Rigidbodies so that the objects would come to rest by themselves even if they don't collide.
  • Use a sleepVelocity value that is appropriate for the scale of your level. Remember that 1 unit in Unity is 1 meter in the physics-engine. Ideally your objects would be in a realistic scale.
  • Maybe also try increasing the Min Penetration for Penalty value in the physics settings. This also depends on your world scale.

Answered by bummzack on January 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP