Матчасть
October 15, 2022

Анимация движения на разные расстояния

Задача: сделать анимацию перемещения объекта из одной точки в другую. При этом расстояние между точками может быть разное, как очень маленькое, так и очень большое.

Пример 1: Сделать перемещение аватара персонажа по карте между ключевыми точками.

Перемещение аватара на разное расстояние

Пример 2: Сделать анимацию смещения полоски прогресса. В этом случае, мы хотим сделать анимацию достаточно долгой, чтобы игрок успел обратить на нее внимание.

Свечение на конце прогресс-бара для заметности даже маленьких смещений

Пример 3: Сделать пролистывание списка от элемента X до элемента Y.

Как правило, такие анимации делаются через твины (tweens). Это значит, что указываются координаты начальной и конечной точки, время, отводимое на перемещение, и функция плавности.

Обычно мы ожидаем нелинейный характер передвижения: Мы хотим, чтобы объект разгонялся в начале и притормаживал в конце.

В функциях с разгоном в начале и притормаживанием в конце есть слова «In» и «Out»

Время

Обычно в настройки выносится время, которое будет отводиться на такую анимацию.

Этот вариант может не нравиться тем, что на больших расстояниях объект будет двигаться слишком быстро. А если увеличить время, то на маленьких расстояниях — слишком медленно. Придется искать компромисс.

Впрочем, такой логики иногда достаточно.

Cредняя скорость

Можно вынести не само время, а зависимость времени от расстояния — среднюю скорость на перемещение (Movement AvgSpeed). И соответственно высчитывать время на анимацию, как:

Time = Distance / MovementAvgSpeed;

Но, настроив приемлемую скорость для одного из случаев, мы получим плохой результат на другом расстоянии. Например, на маленьком расстоянии объект будет слишком быстро перескакивать к новой точке.

Временные рамки

Попробуем выразить разговорным языком, что же нам нужно в идеале: «Надо, чтобы объект двигался от 2 до 5 секунд в зависимости от того, насколько далеко ему нужно проехать».

То есть, по сути, нам подходит использование средней скорости, но нужно еще наложить ограничения на получаемое время. Ввести MinTime и MaxTime — минимальное и максимальное время на перемещение.

Итого, у нас получается три параметра для анимации:

  • Movement AvgSpeed
  • MinTime
  • MaxTime
// Рассчитанное время будет >= MinTime, но <= MaxTime
Time = Mathf.Clamp(Distance / MovementAvgSpeed, MinTime, MaxTime);

Если выразить полученную функцию графиком:

Как настраивать

  • Сначала уберите ограничения (поставьте MinTime = 0, а MaxTime = 999999).
  • Затем настройте для себя приемлемую скорость на «среднем расстоянии»
  • Установите ограничения. Подумайте, сколько времени может длиться самая долгая и самая быстрая анимация