Автор Tiny Starpilot делает процедурную анимацию ключевым элементом проекта. Она даёт:
- более отзывчивых и «сочных» персонажей;
- модульные анимационные ассеты, которые можно переиспользовать на разных скелетах;
- возможность опираться на собственную экспертизу в IK вместо типовых решений движка.
Зачем свой IK, если в движке уже есть
В Unreal есть встроенный IK и Control Rig, но автор пишет собственные солверы, чтобы:
- получать более «плотный» (tighter) результат, чем даёт общий FABRIK;
- уменьшить количество boilerplate в Blueprints/графах;
- иметь модульные узлы, которые автоматически находят и координируют нужные кости с минимальной настройкой.
Двухкостный IK: постановка задачи
Рассматривается самый частый случай — цепочка из двух костей (плечо–локоть–кисть или бедро–колено–стопа). Задача: по базовой позе конечности вычислить минимальные повороты плеча и локтя, чтобы конечная точка (кисть/стопа) попала в заданный таргет.
Эта задача удобна тем, что имеет аналитическое решение через закон косинусов. Известны длины костей A и B и расстояние C от корня до таргета — из этого вычисляется угол в «локте».
Ключевые шаги решения
- Подготовка данных. Все трансформы костей приводятся к одной системе координат (в Unreal — Component Space). Если изначально трансформы относительные, они композируются/раскладываются обратно после решения.
- Вычисление длин костей. Определяются длины верхней и нижней кости и максимальная досягаемость (UpperLen + LowerLen минус небольшой зазор, чтобы избежать выпрямления в линию и связанных с этим артефактов).
- Плоскость решения. Три точки (плечо, локоть, кисть) всегда лежат в плоскости. Строятся два базисных вектора:
- направление от плеча к кисти (ToEnd);
- пол-вектор (Pole Vector) — проекция плечо–локоть на плоскость, перпендикулярную ToEnd.
- Поворот к таргету. Таргет-контакт обрезается по максимальной длине руки. Строится направление ToTarget и кватернион ToTargetSwing = FromToRotation(ToEnd, ToTarget). Им поворачивается и пол-вектор.
- Закон косинусов. По длинам костей и расстоянию до таргета считается угол в «локте» (θ). Проверяется деление на ноль. Через cosθ и sinθ находятся смещения вдоль направления к таргету и вдоль пол-вектора, что даёт новые позиции локтя и кисти.
- Повороты костей. Новые позиции переводятся в повороты:
- RootSwing — поворот плеча, выравнивающий старое и новое направление на локоть;
- MidSwing — поворот локтя, вычисленный после учёта RootSwing, и применяемый к локтю и кисти.
- Запись результата. Обновляются позиции и ротации всех трёх суставов.
Использование в анимационном графе
В узле FAnimNode_ArmAim (Unreal) двухкостный IK используется для прицеливания рукой:
- берётся базовая поза плеча/локтя/кисти;
- рука почти полностью (99% длины) вытягивается в сторону направления прицеливания через Solve();
- дополнительно считается кватернион Fixup, выравнивающий направление предплечья с вектором прицеливания;
- этим Fixup поворачиваются позиции и ротации всех трёх суставов для точного совпадения направления выстрела.
Unreal умеет считать такие анимационные ноды в параллельных потоках, что позволяет не экономить на математике.
Порт на Unity
В конце приводится полный эквивалентный код двухкостного IK на C# для Unity. Логика полностью повторяет Unreal-реализацию: те же шаги, те же проверки на длину и деление на ноль, использование Quaternion.FromToRotation и Vector3.ProjectOnPlane.
Выводы
- Двухкостный IK с аналитическим решением даёт точный и предсказуемый контроль над руками и ногами.
- Собственный IK-солвер позволяет уменьшить boilerplate и добиться более «плотных» результатов, чем универсальные FABRIK-решения.
- Работа в единой системе координат и небольшой зазор до максимальной длины цепи критичны для стабильности.
- Один и тот же алгоритм легко переносится между Unreal и Unity, что упрощает кросс-движковую разработку.