0
\$\begingroup\$
IEnumerator MoveBack()
{
    yield return new WaitForSeconds(3f);

    float t = 0;
    float duration = 30f;
    while (t < duration)
    {
        t += Time.deltaTime;
        player.rotation = Quaternion.Slerp(player.rotation,
           Quaternion.Euler(player.rotation.x, player.rotation.y + 90f, player.rotation.z),
           t / duration);
        yield return null;
    }
}

If I set the duration to 0.1f, it will rotate too fast to see.

But also if I set duration to 30 it's still not rotating that slow.

Should a lower duration value rotate more slowly, or more quickly?

30 seems almost fine, but is it sensible to set the value so high to make it rotate a bit slower?

\$\endgroup\$
1
  • \$\begingroup\$ Note that you're changing the starting and ending points of your slerp every cycle through the loop. You are still using an incorrectly-written exponential ease-out — I linked you to an explanation of this previously. \$\endgroup\$
    – DMGregory
    Mar 27, 2021 at 13:09

1 Answer 1

2
\$\begingroup\$

This becomes obvious if we walk through the loop step by step. Let's say your duration is 1 second, we're running at 30 FPS, and the object starts with Euler angles (0, 0, 0):

  • On the first loop, we blend between (0, 0, 0) and (0, 90, 0) by a factor of 1/30. 0 + (90-0)*1/30 = 0 + 90/30 = 0 + 3, so that brings us to the angles (0, 3, 0)

  • On the second loop, we blend between (0, 3, 0) and (0, 93, 0), by a factor of 2/30 (your starting and ending points are both re-calculated from where we are now, and your t value accumulates every loop). 3 + (93 - 3)*2/30 = 3 + 90/15 = 3 + 6 = 9, so that brings us to the angles (0, 9, 0)

  • On the third loop, we blend between (0, 9, 0) and (0, 99, 0) by a factor of 3/30, bringing us to (0, 18, 0)

  • On the fourth loop, we blend between (0, 18, 0) and (0, 117, 0) by a factor of 4/30, bringing us to (0, 30, 0)

And so on. Our step size grows linearly with time, because we're changing both the blend factor and the endpoints we're blending between.

It looks like you meant to write something more like this:

Quaternion start = player.rotation;
Quaternion end = Quaternion.Euler(0, 90, 0) * player.rotation;

for (float t = 0; t < 1f; t += Time.deltaTime/duration) {
    player.rotation = Quaternion.Slerp(start, end, t);
    yield return null;
}
player.rotation = end;

Note that we cache our starting and ending points up-front, so they stay fixed in place, and only t changes as it blends us from 0 (all the way at start) to 1 (all the way at end).

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .