How can i reset all forces of a rigidbody? Is deactivating the GameObject the only way?
Anyone?
Setting isKinematic to true will cause the rigidbody to stop moving under force and (as near as I can tell) reset/clear the forces.
rigidbody.isKinematic = false; // rigidbody can move under force
rigidbody.AddForce(Vector3(0,1,0) * 50);
yield WaitForSeconds(1);
rigidbody.isKinematic = true; // stop!
There may be a smarter way to do it thoā¦ and of course your object will stop abruptly/unrealistically.
the kinematic thing ends with weird slow physics after a while
I really just want to reuse the object quickly - like it was respawned. But the only way to reset the rigidbody seems to destroy it. :?
Canāt you just set velocity and angularVelocity to new Vecttor3(0,0,0) ?
No when i do this it ends with weird physics like it happens when setting it to kinematic and back - the objects start spinning more and more for no reason.
seems like
does not mean unrealistic behavior because of the scripts action itself but because physx donāt like it at all.
Hmm, I think I have done it before the way I described and it seemed to work. Do you have other things that might influence the rigidbodies, like joints, constant forces, etc? Are you respawning on the same frame?
Maybe you can try setting drag and angular drag very high for a short while?
After reset Iām adding torque to them - i see no way to reset this without destroying the rigidbody
You might get the right result with rigidbody.Sleep, but it can sometimes do weird things if, say, the object is falling at the time it sleeps.
Yep - I need also a definite way to āresetā a rigid body back to itās defaults so that I can reuse it (rather than destroy it)
Cheers
I do something similar to āpauseā physics controlled balls in my game (mid air) when I pull down the menu, and then reapply their forces when I unpause. I came across that weirdness of slow physics after a while, which was really finicky to work around. But here is what I found after much trial and error:
- setting isKinematic to true will remove all movement and cause your object to āpauseā as desired. So record itās current velocities first in order to reapply them after unpausing.
- donāt Sleep() the object because that seems to cause the slow physics after a while under some strange circumstances.
- before you reset isKinematic to false, deactivate then activate the gameobject (this seems to prevent the slow physics as long as Sleep() is avoided).
Here is pseudo code that I use for pausing and unpausing:
// pause
// record the ball's current velocity make it pause/float mid-air
savedPauseVelocity = myRigidbody.velocity;
savedPauseAngularVelocity = myRigidbody.angularVelocity;
if (myRigidbody.isKinematic == false) {
myRigidbody.velocity = Vector3.zero;
myRigidbody.angularVelocity = Vector3.zero;
}
myRigidbody.useGravity = false;
myRigidbody.isKinematic = true;
// unpause
// to fix that prob where changing iskinematic can make the balls appear to drag, deactivate then
// activate the ball which seems to fix it
gameObject.active = false;
gameObject.active = true;
myRigidbody.useGravity = true;
myRigidbody.isKinematic = false;
myRigidbody.velocity = savedPauseVelocity;
myRigidbody.angularVelocity = savedPauseAngularVelocity;
_AddForce( -velocity, ForceMode.VelocityChange);
get the relative torque from angular velocity and :
_AddRelativeTorque(-torque, ForceMode.VelocityChange);
This way, you donāt ābreakā the physic simulation.
Hey, thanks for the help all. But please explain exactly how I get the relative torque?
Cheers
Ok, Iām still failing on this
My rag doll is initially non-kinematic.
So I guess I need to make it kinematic, reset each rigid body and then make it non-kinematic again???
Iāve tried a yield return null (stall for 1 frame) between setting it kinematic and non-kinematic as I assume the physics needs an update to allow for this.
Any suggestions on a reliable way to alter a kinematic/non-kinematic and ādo stuffā on the body before continuing?
Ƨheers
Did you try or look at the pause/unpause code I shared above? This might help.
Yeah.
Iām trying to recycle objects hence the problem.
I tried the yield after altering their state but it doesnāt feet to work.
Also altering velocity while kinematic complains it should be non-kinematic! (I would of thought the opposite!!)
Hereās what I do per rigid body:
limb.rigidbody.isKinematic = true;
yield return null;
limb.rigidbody.velocity = Vector3.zero;
limb.rigidbody.angularVelocity = Vector3.zero;
limb.rigidbody.inertiaTensorRotation = Quaternion.identity;
limb.rigidbody.inertiaTensor = Vector3.zero;
limb.rigidbody.isKinematic = false;
yield return null;
I assume this make kinematic; I alter everything, and then allow non-kinematic again.
Apparently I canāt set the velocity this way - and Iām not convinced the yields do as I expectā¦
Cheers
You canāt change the velocity and stuff when iskinematic = true. Try doing it in this order:
limb.rigidbody.velocity = Vector3.zero;
limb.rigidbody.angularVelocity = Vector3.zero;
limb.rigidbody.inertiaTensorRotation = Quaternion.identity;
limb.rigidbody.inertiaTensor = Vector3.zero;
limb.rigidbody.isKinematic = true;
limb.rigidbody.isKinematic = false;
Iām not sure setting isKinemetic to true and then false is even necessary. I do it in my pause/unpause code because I want my paused objects to hang mid-air while the user does stuff in the menu (ie: frames happen while it is paused). But it looks like you are just immediately removing velocities and that is it - so changing isKinematic may not be necessary?
Did exactly as you said and get
Supplied NxActorDec is not valid.createActor returns NULL. this occurs on setactiverecursively.
hereās my full code:
void init()
{
character2 = transform.parent.Find("character2");
//print(character2);
Color newColor = character2.renderer.material.color;
newColor.a = 1;
character2.renderer.material.color = newColor;
Transform limb = gameObject.transform; //biped
RESET(limb);
limb = transform.Find("L Thigh");
RESET(limb);
limb = limb.transform.Find("L Calf");
RESET(limb);
limb = transform;
limb = transform.Find("R Thigh");
RESET(limb);
limb = limb.transform.Find("R Calf");
RESET(limb);
limb = transform;
limb = transform.Find("Spine/Spine1");
RESET(limb);
limb = transform.Find("Spine/Spine1/Spine2/Head");
RESET(limb);
limb = transform.Find("Spine/Spine1/Spine2/L UpperArm");
RESET(limb);
limb = transform.Find("Spine/Spine1/Spine2/L UpperArm/L Forearm");
RESET(limb);
limb = transform.Find("Spine/Spine1/Spine2/R UpperArm");
RESET(limb);
limb = transform.Find("Spine/Spine1/Spine2/R UpperArm/R Forearm");
RESET(limb);
//rigidbody.AddForce(-rigidbody.velocity,ForceMode.VelocityChange);
//rigidbody.AddRelativeTorque(-rigidbody.tor
//rigidbody.isKinematic = true;
//rigidbody.isKinematic = false;
//rigidbody.velocity = Vector3.zero;
//rigidbody.angularVelocity = Vector3.zero;
//print(transform.position);
}
void RESET(Transform limb)
{
//return;
if (limb == null)
print("NULL");
print("LIMB:"+limb.name);
limb.rigidbody.velocity = Vector3.zero;
limb.rigidbody.angularVelocity = Vector3.zero;
limb.rigidbody.inertiaTensorRotation = Quaternion.identity;
limb.rigidbody.inertiaTensor = Vector3.zero;
limb.rigidbody.isKinematic = true;
limb.rigidbody.isKinematic = false;
}
Iām not sure what that error is about, but I donāt think itās happening in the RESET function, maybe itās happening in one of the Find calls? Does it say what line the error is happening on?