Comments 21
ИМХО, в данном примере, это баг в реализации функции Update
, имеет мало отношения к самой функции Lerp
.
Для реальных задач это сочетание update+lerp для движения лучше не использовать.
Другой вопрос, который уже задал я сам себе: зачем тогда умножать на Time.deltaTime в методе FixedUpdate()?Потому, что интервал вызова FixedUpdate задается в настройках Юнити, и не является константов в глобальном смысле слова.
У меня больше другое вызывает вопросы — зачем для Lerp статья на хабре? Приведенное в статье использование оной не является багой или фичей, о которой никто не знает — а всего лишь один из вариантов реализации, и поведение его вполне объяснимо и предсказуемо. Так что я немного удивился.
В данном примере lerp по дельте между кадрами между начальной и конечной точкой не даст вообще никакого движения. Максимум – получится дёрганье на месте.
Vector3 destinationPoint;
Vector3 startPoint;
float time;
...
void Start()
{
startPoint = transform.position;
}
void Update()
{
transform.position = Vector3.Lerp (startPoint, destinationPoint, time);
time += Time.deltaTime;
if(time > 1)
{
time = 0;
}
}
как вариант. будет клавно идти от начала до конца, каждый раз возвращаясь в начало.
time += Time.deltaTime;
я вот об этом как раз и говорил :-)
В примере из статьи напрямую Time.deltaTime
используется в качестве параметра.
Код работает. Движение происходит от начальной точки к конечной, с плавным замедлением. А вот предложенный выше в комментарих вариант — это уже истинная линейная интерполяция.
Ваш пример работает только потому, что на каждый Update
меняется начальная точка лерпа, как вы и написали в посте. А Tutanhomon в комментарии выше предложил начальную точку зафиксировать. В этом случае движения как раз не будет.
"популярный шаблон ее использования"
Что делает функция Lerp можно понять (да и надо бы знать) по первой ссылке в гугле. Как программист, я бы сразу задал себе 2 вопроса:
- Зачем передавать каждый раз текущие координаты?
- Зачем передавать Time.deltaTime?
По мне так самый адекватный ответ — сломать себе мозг и получить трудно представимое поведение. Как только узнал про такую функцию (еще где-то до юнити), юзал ее так, как она и предполагает — как написал в комментарии Tutanhomon.
Поэтому я бы с ПОПУЛЯРНОСТЬЮ такого использования бы поспорил. Имхо, адекватные люди так не пишут код.
Вот кстати, если вы такую статью большую написали, сделали бы график нелинейного движения, написали бы закон изменения координат) Исследование настоящее)
Что делает функция Lerp _сама по себе_ — это как раз понятно. И именно эта понятность и затрудняет понимание вышеприведенного кода, где результат уже не линеен. Именно поэтому и статья.
А «график» приведенного движения довольно прост: при стремлении временного интервала к нулю получаем классическую exp(-k*t), где k — некий коэффициент. Собственно, это видно из базового разностного уравнения.
Если подумать, вопрос был даже не в использовании функции так или иначе (в конечном итоге программист сам решает, как ему использовать имеющиеся инструменты). Вопрос, скорее, в том, что в этих самых туториалах раз за разом дается такая форма без объяснения. Что вызывает у людей вопросы. Или не вызывает, в зависимости от.
Для FixedUpdate() заведена своя переменная fixedDeltaTime, которая, судя по названию, должна давать время между его вызовами… Но нет же, сами же разработчики рекомендуют и в FixedUpdate() и в Update() использовать deltaTime, поскольку частота вызовов FixedUpdate() фиксированная-фиксированная, да не очень.
Time.deltaTime — время в секундах затраченное на отображение последнего фрейма, после отображения предпоследнего.
Time.fixedDeltaTime — интервал в секундах, через каждый промежуток fixedDeltaTime вызывается обновление физики и другие фиксированные апдейты, как, например, fixedUpdate()
Также есть момент, что deltaTime вернет вроде бы fixedDeltaTime, если будет использован в fixedUpdate()
Промежутки между вызовами fixedUpdate() фиксированы, но их можно менять для увеличения/уменьшения точности расчета физики.
Еще звучал интересный вопрос, который я не совсем понял: коль скоро значение параметра интерполяции не меняется, зачем там вообще deltaTime?
Для того, чтобы скорость игры оставалась постоянной для любой машины на которой запущена игра.
Пример: если нет deltaTime, то при 100fps и 10fps объект переместиться за разное реальное время, так как в одном случае метод выполнится 100 раз за секунду, а в другом лишь 10.
«Еще звучал интересный вопрос, который я не совсем понял: коль скоро значение параметра интерполяции не меняется, зачем там вообще deltaTime?»
Я не понял вопрос человека, а не ответ. Который, в свою очередь, очевиден.
Об использовании и понимании функции Lerp в Unity3D