Как автор Tiny Starpilot пишет свой IK и выжимает максимум из процедурки — Game Design Radar
← Все посты

Как автор Tiny Starpilot пишет свой IK и выжимает максимум из процедурки

15.12.2025
Как автор Tiny Starpilot пишет свой IK и выжимает максимум из процедурки

Автор Tiny Starpilot делает процедурную анимацию ключевым элементом проекта. Она даёт:

  • более отзывчивых и «сочных» персонажей;
  • модульные анимационные ассеты, которые можно переиспользовать на разных скелетах;
  • возможность опираться на собственную экспертизу в IK вместо типовых решений движка.

Зачем свой IK, если в движке уже есть

В Unreal есть встроенный IK и Control Rig, но автор пишет собственные солверы, чтобы:

  • получать более «плотный» (tighter) результат, чем даёт общий FABRIK;
  • уменьшить количество boilerplate в Blueprints/графах;
  • иметь модульные узлы, которые автоматически находят и координируют нужные кости с минимальной настройкой.

Двухкостный IK: постановка задачи

Рассматривается самый частый случай — цепочка из двух костей (плечо–локоть–кисть или бедро–колено–стопа). Задача: по базовой позе конечности вычислить минимальные повороты плеча и локтя, чтобы конечная точка (кисть/стопа) попала в заданный таргет.

Эта задача удобна тем, что имеет аналитическое решение через закон косинусов. Известны длины костей A и B и расстояние C от корня до таргета — из этого вычисляется угол в «локте».

Ключевые шаги решения

  1. Подготовка данных. Все трансформы костей приводятся к одной системе координат (в Unreal — Component Space). Если изначально трансформы относительные, они композируются/раскладываются обратно после решения.
  2. Вычисление длин костей. Определяются длины верхней и нижней кости и максимальная досягаемость (UpperLen + LowerLen минус небольшой зазор, чтобы избежать выпрямления в линию и связанных с этим артефактов).
  3. Плоскость решения. Три точки (плечо, локоть, кисть) всегда лежат в плоскости. Строятся два базисных вектора:
    • направление от плеча к кисти (ToEnd);
    • пол-вектор (Pole Vector) — проекция плечо–локоть на плоскость, перпендикулярную ToEnd.
  4. Поворот к таргету. Таргет-контакт обрезается по максимальной длине руки. Строится направление ToTarget и кватернион ToTargetSwing = FromToRotation(ToEnd, ToTarget). Им поворачивается и пол-вектор.
  5. Закон косинусов. По длинам костей и расстоянию до таргета считается угол в «локте» (θ). Проверяется деление на ноль. Через cosθ и sinθ находятся смещения вдоль направления к таргету и вдоль пол-вектора, что даёт новые позиции локтя и кисти.
  6. Повороты костей. Новые позиции переводятся в повороты:
    • RootSwing — поворот плеча, выравнивающий старое и новое направление на локоть;
    • MidSwing — поворот локтя, вычисленный после учёта RootSwing, и применяемый к локтю и кисти.
  7. Запись результата. Обновляются позиции и ротации всех трёх суставов.

Использование в анимационном графе

В узле FAnimNode_ArmAim (Unreal) двухкостный IK используется для прицеливания рукой:

  • берётся базовая поза плеча/локтя/кисти;
  • рука почти полностью (99% длины) вытягивается в сторону направления прицеливания через Solve();
  • дополнительно считается кватернион Fixup, выравнивающий направление предплечья с вектором прицеливания;
  • этим Fixup поворачиваются позиции и ротации всех трёх суставов для точного совпадения направления выстрела.

Unreal умеет считать такие анимационные ноды в параллельных потоках, что позволяет не экономить на математике.

Порт на Unity

В конце приводится полный эквивалентный код двухкостного IK на C# для Unity. Логика полностью повторяет Unreal-реализацию: те же шаги, те же проверки на длину и деление на ноль, использование Quaternion.FromToRotation и Vector3.ProjectOnPlane.

Выводы

  • Двухкостный IK с аналитическим решением даёт точный и предсказуемый контроль над руками и ногами.
  • Собственный IK-солвер позволяет уменьшить boilerplate и добиться более «плотных» результатов, чем универсальные FABRIK-решения.
  • Работа в единой системе координат и небольшой зазор до максимальной длины цепи критичны для стабильности.
  • Один и тот же алгоритм легко переносится между Unreal и Unity, что упрощает кросс-движковую разработку.
check_circle Факт-чекинг
Статья прошла проверку. Фактологических ошибок не выявили.