|
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. 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.
(comments are locked)
|
|
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.
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!
Oct 07 '11 at 01:15 PM
sriram90
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?
Oct 07 '11 at 01:17 PM
sriram90
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?
Oct 07 '11 at 01:35 PM
syclamoth
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.
Oct 07 '11 at 05:29 PM
aldonaletto
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
Oct 12 '11 at 12:23 PM
sriram90
(comments are locked)
|
|
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.
Oct 07 '11 at 03:09 PM
sriram90
(comments are locked)
|
|
There is a free rigidbody sleep script on the Unity Asset Store.
(comments are locked)
|

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!