Calculating 90 degree rotation in world space

I’m stuck. I want to calculate a new local rotation, 90 degrees from the current local rotation in World Space (not local space).

The “local axis problem” I’m having is that the local axes are no longer aligned with the world axes, so what should be “rotate left around world Y”, becomes “rotate left around world Z” once the object is rotated 90 degrees around X.

The code I have so far (exhibits the local axis problem):

startRot = transform.rotation;
endRot = startRot*Quaternion.AngleAxis(90, Vector3.right);
transform.rotation = Quaternion.Lerp (startRot, endRot, rotTime/rotDuration);

Thanks in advance!
:?:

Have you tried it without the Lerp? Does that work?

(PS: Quaternion.Slerp works better than Quaternion.Lerp)

I had the same problem with this, and it was way harder than I thought. In fact I didn’t really come up with a good solution (although it works fine, it’s a bit convoluted and only really applies to that project), so I’d be interested to hear a good answer as well. :slight_smile: It’s probably simple but I was stuck too…

–Eric

Problem fixed - many thanks to Neil and the IRC clan. Attach this script to an object to get a smooth 90 degree rotation controlled by the arrow keys.

var rotDuration: float = 1;
var rotTime: float = 0;
var startRot: Quaternion;
var endRot: Quaternion;
var dir: Vector3;
var isFlipping: boolean = false;
	
function Update () {
	if (Input.GetKeyDown("up")) {
		dir = Vector3.right;
		updatePos();
	} else if (Input.GetKeyDown("down")) {
		dir = Vector3.left;
		updatePos();
	} else if (Input.GetKeyDown("right")) {
		dir = Vector3(0,-1,0);
		updatePos();
	} else if (Input.GetKeyDown("left")) {
		dir = Vector3.up;
		updatePos();
	}
}

function updatePos () {
	if (isFlipping) return;
	isFlipping = true;
	startRot = transform.rotation;
	// ** this is incorrect as once rotated the control axes swap
    // endRot = startRot*Quaternion.AngleAxis(90, dir);
	
	// ** this is right - qauternions are not commutative!
    endRot = Quaternion.AngleAxis(90, dir) * startRot;
	
	for (rotTime=0.0; rotTime<rotDuration; rotTime += Time.deltaTime) { 
   		transform.rotation = Quaternion.Lerp (startRot, endRot, rotTime/rotDuration); 
   		yield;
	}
	isFlipping = false;
}