Self Levelling a GameObject

I have a game object which is being animated using kinematics (for too many reasons to go into) that fly around a scene. However, I need to do some collision detection and have the GO bump into things.

So, I have attached a riged body… However, there is an issue. When the game object bumps into something it throws off its rotation, and the object just goes mental and whips arround the scene because all its axis have been thrown off.

So, (basically), after an impact I need to quickly kill the physics influence and reset the rotation to 0 on the X and the Z axis but still give the player control over the Y.

I tried doing the following but it doesn’t work (it seams to lock out the Y rotation too).

	Quaternion rotationDrift = Quaternion.Lerp (transform.rotation, Quaternion.Euler (0, 0, 0), maxSpeed * Time.deltaTime); 
	Quaternion recoverRotation = Quaternion.Euler (rotationDrift.x, transform.rotation.y, rotationDrift.z);
	transform.rotation = recoverRotation;

Is there a way to achieve what I want to do? moving to a physics only model is not really a possibility because of other things I need to do.

Hi, try doing something like this, called every Update. It should sort out your rotation.

//You must set your Gravity Vector!
//and it must be normalised(have a magnitude of 1)!!!!

private var vGravity_Direction : Vector3;
private var vLocal_X : Vector3;
private var vLocal_Z : Vector3;
private var qNew_Rotation = Quaternion();

function subReset_Orientation() {

    //Note : Local X is the Left/Right Direction.
    //     : Local Z is the Forward/Backward Direction.
    //Get New X Vector via Cross Reference of Current Forward Vector with Gravity Vector.
    vLocal_X = Vector3.Cross(tMy_Transform.forward, vGravity_Direction);
    //Get New Z Vector via Cross Reference of New X Vector with Gravity Vector.
    vLocal_Z = Vector3.Cross(vGravity_Direction, vLocal_X);
    vLocal_Z = vLocal_Z.normalized;
    //Re-Set Rotation orientation.
    qNew_Rotation.SetLookRotation(vLocal_Z, -vGravity_Direction);
    tMy_Transform.localRotation = qNew_Rotation;

tMy_Transform is my cached transform for the object that I am adjusting.
You can use just use “transform” if you want to, thought caching is faster than not doing.

You can also use this for spherical gravity(like Mario Galaxy) via adjusting your current gravity direction vector, without getting gimbal lock!