Forums › 💬 Slate Sequencer › ⚙️ Support › Animating local transform? › Reply To: Animating local transform?
I played around with this a bit more. The issue is that Lerp just does plain old math, without any concern for the different ways Vector3s can be equivalent. So, (180,0,0) is the same as (-180,0,0), but will produce different lerp results when used as the Start or End of a Lerp.
So, before calling Lerp to determine the rotation, I first need to clean up the target rotation so that none of the component differences (Mathf.Abs(original.x – target.x), for example) exceeds 180. Here’s what I’m doing, which seems to work properly, though I assume there’s a more efficient approach. The following is the OnUpdate method of my LocalRotateTo action clip. Note the use of GetShortestResult to adjust the targetRotation to create an equivalent Vector3 that minimizes the rotation:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
protected override void OnUpdate(float deltaTime) { if (length == 0) { actor.transform.localEulerAngles = targetRotation; return; } targetRotation = GetShortestResult(originalRotation, targetRotation); actor.transform.localEulerAngles = Easing.Ease(interpolation, originalRotation, targetRotation, deltaTime / length); } private Vector3 GetShortestResult(Vector3 original, Vector3 target) { // Ensure the rotation between any two components doesn't exceed 180 degrees var x = target.x; var y = target.y; var z = target.z; while (original.x + 180 < x) x -= 360; while (original.x - 180 > x) x += 360; while (original.y + 180 < y) y -= 360; while (original.y - 180 > y) y += 360; while (original.z + 180 < z) z -= 360; while (original.z - 180 > z) z += 360; return new Vector3(x, y, z); } |
So now my LocalRotateTo always takes the shortest rotation instead of doing backflips or pirouettes. 🙂
