need help in rigid body sleep

Hi All,

I came near to finish this problem but there is a small problem remain with me.

What am trying to do is, i have lot of meshes with rigid body attached. consider the all meshes are constructed like wall. am hitting the wall with a ball. the wall will get scatter when 'll hit. ok here i need to do find all the rigid bodies are in sleep after hit by the ball. am finding all the objects with tag. after all rigid bodies get sleep i need to move my camera.

// here is my code about this process.

private GameObject[] rigid;
    void Awake()
	{
		rigid = GameObject.FindGameObjectsWithTag("wallobject");	
	}
	void Update()
	{
		foreach(GameObject rigids in rigid)
		{
			if(rigids.rigidbody.velocity.y == 0)
			{
				if(rigids.rigidbody.IsSleeping())
				{
				Debug.Log(" "+rigids.name);	
				}
			}
		}
	}

am getting here all the name of the objects correctly. i just need a boolean variable to pass all the rigid bodies are sleeping. how can i achieve it. if i got the boolean variable isSleep = true, the problem 'll get over. help meeee…

Note : i have asked a question already similar to this. but i couldn’t get any response. but i have improved in my points compared to old question.

You can set a boolean variable to true before starting the verification loop, and set it to false if any rigidbody isn’t sleeping, like this:

    bool allSleeping; // boolean variable to tell if everybody is sleeping
    
    void Update()
    {
       allSleeping = true; // set to true before start checking
       foreach(GameObject rigids in rigid)
       {
         if (rigids.rigidbody.velocity.y != 0 || !rigids.rigidbody.IsSleeping())
          {
            allSleeping = false; // any awake rigidbody will set it to false
          }
         }
         // allSleeping is true if everybody sleeping
       }
    }

But I think it’s better not to check if the rigidbody.velocity.y is zero: a sleeping rigidbody doesn’t move anywhere, so its velocity is zero anyway. It would simplify and optimize your loop:

    bool allSleeping;
    
    void Update()
    {
       allSleeping = true;
       foreach(GameObject rigids in rigid)
       {
         if (!rigids.rigidbody.IsSleeping()) allSleeping = false;
       }
    }

EDITED: If the rigidbodies are lasting to long to go sleep, you can use a brute force approach: wait for a decent amount of time, then reduce yourself the velocity and angular velocity of all rigidbodies until all of them rest in peace: when the player shoot, assign to timer a suitable time in seconds (the time may vary depending on the level complexity) and start checking allSleeping; if all rigidbodies go sleep earlier, allSleeping goes true; if not, after the specified time all awake rigidbodies start getting their velocities faded out, and in a little time they all will sleep - and allSleeping becomes true, as usual.

The fading factor decreases the velocities exponentially; the fadeOut variable controls this: the closer to 1.0f, the longer it will take to break (0.9 to 0.99 is a reasonable range). Since we’re modifying physics stuff, I moved the whole thing to FixedUpdate:

  public bool allSleeping = false;
  // fade factor: closer to 1.0 take more time to sleep
  public float fadeOut = 0.9f;
  // set the time in seconds to start fading velocities
  public float timer = -1.0f;

  void FixedUpdate()
  {
    allSleeping = true; // set to true before start checking
    foreach (GameObject rigids in rigid)
    {
      if (!rigids.rigidbody.IsSleeping())
      { // if any rigidbody is awake...
        allSleeping = false; // flag goes false
        if (timer >= 0f){ 
          timer -= Time.deltaTime; // and decrement timer
        }
        else // if free time ended...
        {
          // start reducing the rigidbody velocities
          rigids.rigidbody.velocity *= fadeOut;
          rigids.rigidbody.angularVelocity *= fadeOut;
        }
      }
    }
  }

If a rigidbody is sleeping, its velocity will be zero by definition. So, you don’t need to have the check for rigidbody.velocity in there! The only problem with doing it this way, is that there is no guarantee that all the rigidbodies will fall to rest eventually- some might end up moving slightly, or fall out of the world. In this case, you might also want to include some catchall- either a timer, or something for rejecting rigidbodies with a position.y value less than say -2000, or velocity.magnitude of less than 0.1.

There is a free rigidbody sleep script on the Unity Asset Store.