- Home /
Quaternion.Slerp issue
I'm trying to rotate my camera using Quaternion.Slerp. I'm getting the desired rotation angle, but it's snapping to the rotation. I declared a float called "elapsed" and attempted to increment it during a while loop within the coroutine. The issue is that on key press my "elapsed" float is jumping straight to the "spinTime" float value. Here's the section of relevant code:
private IEnumerator Spin()
{
elapsed = 0;
while (elapsed < spinTime)
{
elapsed += Time.deltaTime;
camHolder.transform.rotation = Quaternion.Slerp(transform.rotation, spinTarget, spinTime);
}
yield return null;
}
Thanks in advance, everyone :)
I also tried dividing "elapsed" by "spinTime" in Quaternion.Slerp as advised by someone else, but it made no difference.
private IEnumerator Spin()
{
elapsed = 0;
while (elapsed < spinTime)
{
elapsed += Time.deltaTime;
camHolder.transform.rotation = Quaternion.Slerp(transform.rotation, spinTarget, elapsed / spinTime);
}
yield return null;
}
Answer by Neran28 · Nov 12, 2019 at 12:36 AM
Put the yield return at the end of the loop.
The elapsed / spintime addition is also required.
Awesome, thank you! I've been trying to learn to code on and off for years, this is the farthest I've gotten thanks to awesome people like you. If you have some spare time, would you $$anonymous$$d elaborating on why the elapsed / spintime addition is needed?
Well slerp is a type of linear interpolation. The s in slerp means spherical. It behaves a bit different than lerp. But in general a linear interpolation takes 3 params. 2 values that are from a specific domain and the third one is the stepsize clamped between 0 and 1. Imagine a 2D carthesian grid. In this case lerp takes two pairs of (x,y) coordinates as the domain params. Lets say (1, 0) and (2, 2). You can then specify the 3. param lets say 0.5f. The lerp function then returns the value from that domain at step 0.5 which in this case is (1.5, 1). You can imagine a straight line between both points (1,0) and (2,2). The 3. param can be seen as a percentage. 0 yields your first param (1,0) and 1 yields your second (2,2) and everything in between 0 and 1 is a value on that line. 0.2 yields the value that lies one fifth along the line seen from the first point in the direction to the second. 0.5 is exactly the midpoint between both points. In lerp the distant for each step is the same. In slerp it is not equidistant. You can also interpolate other things than positions like rotations or colors.
Btw: yield returning at the end of loop makes your coroutine to return after each loop iteration and it will resume with the next iteration in the next frame. This results in an animation. What you did before is calculating the complete animation in one single frame which resulted in just displaying the end of your animation.
Elapsed / spintime is needed because if you just use spintime then the function returns always the same value. And if it is >= 1 it always yields your second param. You could just use elapsed as your third param but this would result in an animation duration of 1 second. This is a result of adding deltatime to your variable. I think that should be clear? If you want your animation to last for spintime seconds then you have to divide your elapsed time by the spintime. Here a few examples with spintime == 3. Elapsed == 0: 0/3=0 which yields the first param. Elapsed == 1: 1/3=0.3333 yields the rotation at one third of the spin. Without the division the animation would be completed at this point. Elpased == 3: 3:3=1 which yields yor second param. End of your animation.