- Home /
Preventing rotation of rigidbody at a specific rotation
I have a rigidbody with 4 wheel colliders attached. To get the rigidbody airborne I first add a force to the front of rigidbody then I add a force to the back of the rigidbody. This causes the it to become airborne.
Once the rigidbody has become airborne I want it to stop rotating and remain level to the surface normal below it.
The closest I have come to doing this is to do a raycast downward from the rigidbody to get the hit.normal then monitor the dot product between hit.normal and the rigidbody transform.up and once this value is close to 1 stop kill all angular velocity.
However the problem Im experiencing is since im using forces to make the rigidbody airborn the Z value is sometimes not level thus causing the dot product to never be near 1.
I also thought freezing the Z and Y rotations would help stabilize it a bit but I still get some rotation along the Z axis.
I then tried to store the rotation of the rigidbody prior to becoming airborne and rotate it back to that rotation once airborne but I could not get it to rotate smoothly. And it failed in certain cases such as if it became airborne on an incline and the surface it would land on is level.
Here is a little Visual representation of what Im describing as well as some code I currently have. Id apperiate any advise or suggestions. Thanks.
void Grounded_Update()
{
if(controller.OllieInput())
{
rigidbody.constraints = RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
rigidbody.AddForceAtPosition(backForce,backForceLoc.transform.position);
//Add back force after a certain time
Invoke ("addingForce",timeBetweeenSecondForce);
rigidbody.constraints = RigidbodyConstraints.None;
currentState = PlayerStates.Airborne;
}
void Airborne_FixedUpdate()
{
if(!isBoardLevel)
{
RaycastHit hit;
//sometimes doesnt level off since the z axis rotation is not near 0
//the force will cause the board to roll a bit
if(Physics.Raycast(transform.position, -transform.up, out hit))
{
float dot = Vector3.Dot(transform.up,hit.normal);
if(dot <= 1 && dot >= 0.999)
{
rigidbody.angularVelocity = Vector3.zero;
isBoardLevel = true;
}
}
}
}