Автор разбирает, как спроектировал и прототипировал «аниме»-хоминг‑ракеты, делая упор не на код, а на геометрию движения.
Итеративное vs. замкнутое (closed-form) движение
Выделяются два подхода к движению объектов:
- Итеративный — каждый кадр позиция обновляется по скорости (интеграция, метод Эйлера). Удобен, когда входные данные меняются каждый кадр (управление игроком, физика).
- Замкнутая форма (closed-form) — траектория задаётся аналитически как параметрическая кривая, и по времени t (0–1) вычисляется позиция. Пример — кубическая кривая Безье.
Базовая траектория: кубическая Безье
Для хоминг‑ракеты используется кубическая кривая Безье с четырьмя точками:
- P0 — старт (дуло оружия)
- P3 — цель (поверхность в точке попадания)
- P1 — точка перед стрелком (задаёт начальное направление)
- P2 — точка, вынесенная от поверхности цели (задаёт заход на цель)
Позиция ракеты вычисляется как CalcBezierPos(P0, P1, P2, P3, t), где t = elapsed / duration. Это даёт полный контроль над временем полёта (duration) без решения сложной физической задачи попадания.
Производная кривой (CalcBezierDeriv) даёт касательный вектор — направление движения. Деление на duration даёт скорость в единицах «метры в секунду».
Добавление «сока»: шумовая «змейка» вокруг траектории
Чтобы уйти от «гладкого» полёта и приблизиться к аниме‑ракетам с хаотичными траекториями, к базовой кривой добавляется шум:
- Используется Perlin/Simplex noise — псевдослучайная, но гладкая функция.
- Нужно, чтобы смещение было нулевым в начале и в конце, иначе ракета не совпадёт с дулом и точкой попадания.
- Для этого шум умножается на огибающую, равную 0 на концах и 1 в середине (квадратичная функция вида Envelope = 1 — (1 — 2 * t)^2).
Два независимых значения шума используются как локальные координаты X и Y смещения (Z = 0). Затем этот локальный вектор умножается на ориентационный фрейм, выровненный по касательной кривой, и добавляется к позиции по Безье.
Проблема фреймов: кручение и Rotation Minimizing Frames
Если просто строить ориентацию ракеты через Quaternion.LookRotation(derivative) с фиксированным «верхом», возникают артефакты:
- Фрейм сильно «крутится» вокруг оси движения, особенно на вертикальных участках.
Нужны Rotation Minimizing Frames (RMF) — фреймы, которые минимизируют кручение вдоль кривой. Общий вывод RMF сложен, но есть простой и дешёвый метод Double Reflection (описан в статье 2006 года):
- Хранится текущий фрейм (кватернион).
- На каждом шаге берётся текущий нормаль и касательный вектор из фрейма.
- С помощью двух последовательных отражений (по вектору от старой позиции к новой и по разнице касательных) вычисляется новая нормаль.
- Новый фрейм собирается через Quaternion.LookRotation(t1, n1), где t1 — новая касательная, n1 — обновлённая нормаль.
Этот метод даёт плавно меняющийся фрейм без резких скручиваний, что критично для красивого шума вокруг траектории.
Выводы
- Хоминг‑траекторию удобно задавать кубической кривой Безье, если известны старт и цель и важен точный тайминг попадания.
- Производная Безье даёт направление и скорость движения без физической симуляции.
- Аниме‑стиль достигается добавлением Perlin/Simplex noise в локальных координатах с огибающей, обнуляющей смещение в начале и конце.
- Наивные фреймы по LookRotation вызывают кручение; для стабильного смещения вдоль кривой нужны Rotation Minimizing Frames.
- Метод Double Reflection даёт простой и дешёвый способ обновлять RMF по кривой в реальном времени.