- Home /
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.
So, what about your code here isn't working? Except for some details, it seems to do exactly what I think you want it to. I would recommend getting rid of the check for (velocity whatever == 0)- this will almost never return true, because rigidbodies never really stop moving until they actually fall asleep!
Answer by aldonaletto · Oct 07, 2011 at 10:57 AM
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; } } } }
Hi aldonaletto , i have a question here...the velocity only gets zero when the rigid bodies in rest..if the velocity not in zero means there 'll be little bit of shake remain available. am i correct? here i need find rigid body in sleep as well as no movements in bodies!
i need to move camera when all the scattered pieces of wall remain no movements and sleep. so only i'm trying to use the velocity here. give a suggestion if i'm saying anything as wrong?
aldonaletto's code should do what you are asking for! I'm not sure what part of it is not working for you. Can you tell us what errors are occuring?
According to the docs, Physx don't do anything to a rigidbody that is considered sleeping. Since this little shaking you've mentioned is produced by Physx, when the rigidbody starts sleeping Physx don't move it anymore - gravity effects, bouncing etc. all get stopped. The rigidbody may continue moving only if it's resting over some other moving thing - not a "wallobject", since you are checking all of them.
hi aldonaletto ... you 're saying that is the movement is producing by physics.I'll give a perfect example to u.... did u check "Angry Birds" game. the camera 'll move back to throwing position when the movements on hitted objects (glass pieces,wooden pieces etc..) will get end. i need like the similar movements? still i couldn't get exact answer. if u check angry birds game you may notice it.
Waiting for your reply
Answer by syclamoth · Oct 07, 2011 at 01:34 PM
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.
@syclamoth : yeah now i got the thing what is going on with rigidbody...yes you're correct. when i tried with only rigidbody.IsSleeping() i saw with still movements like you say as "some might end up moving slightly". thats why i tried to do with velocity. i'll try with magnitude. i need the exactly as after the movements got end i need to move the camera.
Answer by create3dgames · Oct 07, 2011 at 06:01 PM
There is a free rigidbody sleep script on the Unity Asset Store.
Your answer
Follow this Question
Related Questions
Get Rigidbodies to Sleep Faster 1 Answer
Rigidbody not sleeping 1 Answer
What does rigidbodies sleeping have to do with collision detection? 0 Answers
how do you tell if a rigidbody is awake 1 Answer
Why are my Rigidbodies not sleeping? 0 Answers