Smooth rotation in 90° increments

I have a puzzle in my game where there is a painting on a wall. The painting is broken up into a 4x6 grid of cubes (only one face of each is visible), and each cube is rotated on the x axis so that the image is scrambled.

The goal of the puzzle is to rotate each of the pieces until the picture is properly formed.

I know how to make the puzzle work, but not exactly the way I wanted to.

I was trying to make it so that each time a cube was clicked, it rotated 90° a second and stopped at each 90° increment.

Of course, Euler angles are all funky so I was having a hard time getting it to work properly, so I just have them instantly rotating 90° each click.

The code I was using while trying to make a smooth rotation is as follows:

 var rotationState: boolean = false;
    
    function OnMouseDown(){
    	rotationState = true;
    }
    
    function Update () {	
    	if (rotationState == true && transform.eulerAngles.x >=0 && transform.eulerAngles.x < 90){
    		transform.Rotate(90 * Time.deltaTime, 0, 0);
    		if (transform.eulerAngles.x >= 90){
    			rotationState = false;
    		}
    	} else if (rotationState == true && transform.eulerAngles.x >=90 && transform.eulerAngles.x < 180){
    		transform.Rotate(90 * Time.deltaTime, 0, 0);
    		if (transform.eulerAngles.x >= 180){
    			rotationState = false;
    		}
    	} else if (rotationState == true && transform.eulerAngles.x >= 180 && transform.eulerAngles.x < 270){
    		transform.Rotate(90 * Time.deltaTime, 0, 0);
    		if (transform.eulerAngles.x >= 270){
    			rotationState = false;
    		} 
    	} else if (rotationState == true && transform.eulerAngles.x >=270 && transform.eulerAngles.x < 360){
    		transform.Rotate(90 * Time.deltaTime, 0, 0);
    		if (transform.eulerAngles.x >= 360){
    			rotationState = false;
    		}
    	}
    }

The code worked for the first two clicks, and then the rotations started to get strange.

Does anyone have any idea how I can achieve the desired effect?

There are lots of ways to do what you want in Unity. Here is one. It requires that you set ‘vCurr’ to the starting rotation in the Inspector.

#pragma strict

var speed = 90;
var vCurr : Vector3 = Vector3.zero;

private var vNew  : Vector3 = Vector3.zero;

function Start() {
	transform.eulerAngles = vCurr;
	vNew = vCurr;
}

function Update() {
	vCurr = Vector3.MoveTowards(vCurr, vNew, speed * Time.deltaTime);
	transform.eulerAngles = vCurr;
}

function OnMouseDown() {
	if (vCurr == vNew) 
		vNew.x += 90.0;
}

Here is a second one. It is a relative rotation using Quaternions. It is a bit harder to understand than the first one, but it does not require setting the rotation in the inspector.

#pragma strict

var speed : float = 90.0;
private var qTo : Quaternion;

function Start() {
	qTo = transform.rotation;
}

function Update () {
	transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, speed * Time.deltaTime);
}

function OnMouseDown() {
	if (transform.rotation == qTo) 
		qTo = Quaternion.AngleAxis(90.0, Vector3.right) * qTo;

}