Slerp issue

I’m trying to rotate my camera to look at 4 different objects around it (90 degrees). The first thing I tried was Vector3.Slerp, but when I told it to go from 270 to 0 it went around backwards and it doesn’t seem to work with negatives. That makes sense but I couldn’t figure out how to get around it. So the next thing I went with was Quaternion.Slerp. This worked much better, 7/8 times. I hit a snag trying to go from 270 degrees to 0 degrees again, only this time it didn’t go backwards, but instead went extremely slow. So I put in slightly different values and found that going to or through 0 from 270 made it go slow (odd to me since 0 to 270 works just fine). If I went through 0 instead of to, it would go really slow until it hit 0 and then go back to normal speed to my target angle.

Sorry about the wall of text. How can I make this work (using either slerp)? Would be helpful to know how to solve both slerp issues for future reference.

I was asked for code so here it is:

void Update(){
		if (rotateCamera){
			Camera.main.transform.rotation = Quaternion.Slerp(Camera.main.transform.rotation, targetAngle, Time.deltaTime*50f/Vector3.Distance(Camera.main.transform.eulerAngles, targetAngle.eulerAngles));
			if (Camera.main.transform.rotation == targetAngle){
				rotateCamera = false;
			}
		}
}

...

if (GUI.Button(new Rect(Screen.width/2 - Screen.height*1.5f/5, Screen.height * 1/20, Screen.height*1/10, Screen.height*1/10), "<")){
						switch (armyByte){
						case 0:
							armyByte = 3;
							targetAngle = Quaternion.LookRotation(new Vector3(-1,0,0));
							break;
						case 1:
							armyByte--;
							targetAngle = Quaternion.LookRotation(new Vector3(0,0,1));
							break;
						case 2:
							armyByte--;
							targetAngle = Quaternion.LookRotation(new Vector3(1,0,0));
							break;
						case 3:
							armyByte--;
							targetAngle = Quaternion.LookRotation(new Vector3(0,0,-1));
							break;
						}
						startTime = Time.time;
						rotateCamera = true;
					}
					if (GUI.Button(new Rect(Screen.width/2 + Screen.height*1/5, Screen.height * 1/20, Screen.height*1/10, Screen.height*1/10), ">")){
						switch (armyByte){
						case 0:
							armyByte++;
							targetAngle = Quaternion.LookRotation(new Vector3(1,0,0));
							break;
						case 1:
							armyByte++;
							targetAngle = Quaternion.LookRotation(new Vector3(0,0,-1));
							break;
						case 2:
							armyByte++;
							targetAngle = Quaternion.LookRotation(new Vector3(-1,0,0));
							break;
						case 3:
							armyByte = 0;
							targetAngle = Quaternion.LookRotation(new Vector3(0,0,1));
							break;
						}
						startTime = Time.time;
						rotateCamera = true;
					}

Your problem is here:

   targetAngle, Time.deltaTime*50f/Vector3.Distance(Camera.main.transform.eulerAngles, targetAngle.eulerAngles)  

…and in particular your division by Vector3.Distance(). If you remove that code, your code would mostly work. But I assume you were trying to do something specific with that code that is not explained here.

The other problem is here:

  if (Camera.main.transform.rotation == targetAngle){

Because the way this usage of Slerp() works, the rotation gets close relatively quickly , but it can take a really long time to before they become equal. And even then, the only reason they become equal is floating point imprecision and the fact there is some slop in the Vector3 comparison. You can do this instead:

if (Quaternion.Angle(Camera.main.transform.rotation, targetAngle) < threshold) { 

…where you set ‘threshold’ at some small, appropriate value.

If you don’t want easing at the end of your rotation you can use Quaternion.RotateTowards() instead. Your equality code will work.

Ok. I edited this in the end. Good luck.