За всё время существования моего канала я выпустил кучу статей о анимации, в большинстве которых я задевал инверсную кинематику и не просто задевал, а восхищался ею.
Некоторые материалы посвящены разработке и образовательному просвещению некоторых аспектов индустрии, думаю справедливо будет задеть и эту интересную тему, но уже в контексте обучения.
В рамках этой статьи я создам простейшую систему постановки ног на препятствие (aka Foot IK), опишу логику работы и покажу пару гифок.
Полный скрипт, если есть заинтересованные - спросить в комментариях.
Логика работы и результат
Сначала заинтригую гифкой с результатом :
Да, анимация не была записана. Я двигаю объект "игрок", а ножки сгибаются сами, а если быть точнее - с помощью алгоритма :
- Из определенных позиций близ бедер вниз стреляются лучи, получая данные о точке контакта и наклоне на "земле"
- Данные отправляются в аниматор, задается степень влияния на каждый кадр анимации на основе прописанных заранее значений
- Аниматор задает косточкам новые значения позиции и поворота
Переменные, функции и луч
Какие переменные нужны?
- Два Transform для текущего положения ног из анимации
- Два Vector3 для будущей позиции, что определится лучом
- Два Quaternion для будущего поворота, что определится лучом
- Две float на "вес" каждой ноги для скрипта
Текущие положения костей запрашиваются через animator.GetBoneTransform, сама функция инверсной кинематики выполняется внутри OnAnimatorIK:
Для того, чтобы кость была подвержена IK, нужно установить ей "вес", что я и делаю из скрипта, но на основе данных из аниматора. Об этом чуть позже.
Сама функция нахождения позиции и поворота выглядит так :
Ей посылается текущая позиция ноги, чуть выше которой происходит выстрел луча вниз. Луч получает точку контакта и наклон поверхности, отправляя их обратно в функцию OnAnimatorIK.
Работа с Animator и кривыми
Этот метод является самым примитивным и простым, поэтому нужны дополнительные мучения над каждой анимацией, а если быть точнее - регулировка кривых.
Задача здесь - расставить весы, которые потом попросит скрипт.
Вес 1 - полное влияние, вес 0 - никакого влияния.
Думаю понятно, что единица нужна в том случае, когда нога на земле, а ноль, когда делается шаг, он записан в анимации. В случае с Idle анимацией (ожидания), весы равны 1 всегда.
Значение из кривых будет отправляться в тот же аниматор, не забудьте создать новые float в переменных с тем же именем, что и кривые, именно из них будет брать значение скрипт.
Больше статей о анимации:
Как движок смешивает анимации
Как создают лицевую анимацию
Создание обычной анимации (кинематики)
Все методы применения инверсной кинематики в играх