Problem rotating a cube with quaternions using lerp

I’m trying to rotate a cube 90 degrees. My script was working until I started to simplify it :frowning: I’ve starred myself blind as to why it’s not working anymore. The cube just rotates a tiny bit and then starts jittering in its rotating movement.

    const float ROTATION_SPEED = 4.0f;

	Quaternion _sourceRotation;
	Quaternion _targetRotation;

	void Start () {
		_sourceRotation = this.transform.rotation;
		_targetRotation = this.transform.rotation;
	}
	
	void Update () {

		float angle = Quaternion.Angle(this.transform.rotation, _targetRotation);
		if (angle < 0.1f) {	
			_sourceRotation = _targetRotation;
			_targetRotation = this.transform.rotation * Quaternion.Euler(90, 0, 0); //a random rotation will be chosen here, but hardcoded right now for simplicity
		}

		this.transform.rotation = Quaternion.Lerp(_sourceRotation, _targetRotation, Time.deltaTime * ROTATION_SPEED);
	}

If I change _sourceRotation to a Transform instead of a Quaternion and store the cubes transform instead or its rotation in _sourceRotation, and in the Quaternion.Lerp use _source.rotation it does the rotation as it should, but I don’t understand why… feeling frustrated

As I just started working with Lerp myself, I don't have a full answer for you, but it might be worth noting that Unity's official video tutorial [here][1] is flawed. Information on why it is flawed: http://www.blueraja.com/blog/404/how-to-use-unity-3ds-linear-interpolation-vector3-lerp-correctly It looks to me like the third argument for Lerp in the last line of your code might be the problem. Again, not sure, but trying to point you in the right direction. [1]: http://unity3d.com/learn/tutorials/modules/beginner/scripting/lerp

Thank you. It was confusing me a bit, since I also seem to recall what hexagonius writes about t [0;1].

1 Answer

1

That’s because Lerp doesn’t work the way you are using it. It interpolates from the first rotation to the second rotation while t == 0 is the first and t == 1 the second rotation value. Assume Time.deltaTime stays constant at 0.05 then t will always be 0.05*4 = 0.2. That’s 20% the first and 80% the second rotation, that’s where the jitter comes from, slightly different deltaTime every frame.

Create another float, use it as t, and add the Time.deltaTime * ROTATION_SPEED to it.
Whenever you reach your target, reset it to 0.

Thanks a lot! However, do you know why it acts correctly when I use a stored transform.rotation instead of a stored quaternion as I write in the latter part of the problem?

That's because saving the rotation creates a copy of the Quaternion and saving the transform a reference to it. With that you are reading the current rotation all the time and the lerp gets ever closer to its target. I would even say it's slowing down at the end.

Ah, yeah! That's right had been wondering about these things already, but only looked to the Quaternions and found out that they were passed by value! Thanks a lot :) I just started to look at some things again and hate when these kinda small things gets in the way.