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
).