Поскольку я долгое время не касался Unity ... но я верю, что вы ошиблись в вычислениях.
Прежде всего, Vector3.MoveTowards(currentPos, toPosition, time)
говорит о
Прогулка от currentPos
до toPosition
с каждым движущимся кадром
определенное расстояние time
.
Таким образом, использование time
в качестве имени сбивает с толку, но хорошо, давайте его сохраним.
Однако, вы заметите в утверждении: time
- это что-то, перемещающее каждый кадр. Но Vector3.Distance(currentPos, toPosition) / duration
- это скорость (м / с), а не (м / кадр). Чтобы сделать это (м / кадр), просто умножьте на Time.deltatime
, то есть (с / кадр).
Во-вторых,
В сопрограмме это означает, что функция повторяется в каждом кадре. В строке float time = Vector3.Distance(currentPos, toPosition) / duration * Time.deltatime;
вы заметите, что time
продолжает уменьшаться при переходе к следующему кадру, когда расстояние становится все меньше и меньше.
Чтобы быть более конкретным, мы можем сделать немного математики. Как правило, это должно быть сделано с исчислением, но давайте упростим это, рассматривая только 2 пункта. Когда положение объекта d = 0 и положение объекта d ~ = 9,9, предположим, что конечная точка равна 10.
В точке 1 объект имеет time
= (10-0) / длительность, полная скорость.
В точке 2 объект имеет time
= (10-9,9) / длительность, 1/10 от полной скорости.
Если вы не хотите, чтобы он перемещался медленнее в каждом кадре, вы не можете оставить значение длительности без изменений. Как и после каждого кадра, вы хотите, чтобы скорость сохранялась, поэтому продолжительность должна уменьшаться с расстоянием.
Чтобы заставить эту физику работать, минус продолжительность за прошедшее время.
Итак, окончательное решение
float time = Vector3.Distance(currentPos, toPosition) / (duration-counter) * Time.deltaTime;
Вот полная функция:
IEnumerator MoveTowards(Transform objectToMove, Vector3 toPosition, float duration)
{
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
Vector3 currentPos = objectToMove.position;
float time = Vector3.Distance(currentPos, toPosition) / (duration - counter) * Time.deltaTime;
objectToMove.position = Vector3.MoveTowards(currentPos, toPosition, time);
Debug.Log(counter + " / " + duration);
yield return null;
}
}