Quaternion.slerp rotates instantly.

Hi Guys and Gals.

I’ve a bit of an issue with Quaternion.slerp … I’ve been looking around for a while but the solutions that are working for others… don’t seem to be working for me, This is what I’m currently doing.

The Expected behaviour is that the unit will rotate, and at the end of it’s rotation, fire() the projectile in waiting.

What happens however, is that the unit rotates instantly, waits a period of time (until timeScale is >= 1), and then fires the projectile in waiting.

The problem is , that the Unit shouldn’t rotate so fast!

	//Rotate Unit(){
	void rotateUnit(){
		if (rotating == false){
			rotateFrom = transform.rotation;
			rotateFrom.x = 0f;
			rotateFrom.z = 0f;
		if (timeScale < 1) {		
			transform.rotation = Quaternion.Slerp (rotateFrom, rotateTo, timeScale / rotateRate );
			timeScale = timeScale + Time.deltaTime;	
		if ((timeScale >= 1) && (rotating == true)){
			if(this.tag == "Player"){
				if(projectileInWaiting != null){
					projectileInWaiting = null;
				rotating = false;
	}	}

rotateTo is set in another function (with x and z set to 0), and it is rotating to the correct position.

timeScale is reset to 0 when a new rotateTo is determined.

curTurnRate is 1.0f.

rotateRate is equal to (1.0f * curTurnRate).

Thanks in advance to anyone who tries to help :)~ I’ve written up other questions and found the answer while I was explaining the problem to you all, sadly, this time that was not the case :frowning:

There are two common ways of using Slerp(). The first way has the start and end position fixed, and the third parameter moves from 0.0 to 1.0 over time. The second way to use Slerp is to use some small fraction (usually something like ‘Time.deltaTime * speed’) as the third parameter, and have the first parameter updated with the current rotation each frame. You are mixing the two. That is, you are updating ‘rotateFrom’ to be the current rotation each time ‘rotateUnit()’ is called, but you are also varying the third parameter from 0 to 1. As you’ve seen, this results in a speedup of the rotation. The fix is to not update rotateFrom after you first set it.

Given the settings, the code should work if you make this fix, but the logic is a bit hinky. In particular, whatever criteria you use for the third parameter of the Slerp() should also be the criteria used on line 12. The only reason that ‘timeScale’ will work is because ‘curTurRate’ is 1.0 (and therefore rotateRate is also 1.0). If the value of curTurnRate is changed, the logic on line 12 will fail.

Actually, My issue was really simple.

I had a condition to get into this method that rotating had to equal true. Therefore rotateFrom was never set. it was rotating from null to q2. Hence it happening instantly.

I’ve changed the bool to check whether I should set a new rotateFrom, and my rotations are functioning correctly now. :slight_smile:

Thanks so much everyone!