От Line Trace до Full Body IK: Как заставить персонажа ходить по любой поверхности
Разберем Как работает риг От эпиков
открываем риг
Идем в функцию FootTrace
Вот тут мы рассчитываем точки для трассировки (Sphere Trace) для каждой ноги
1. Определяем горизонтальную проекцию стопы (X,Y)
Сначала мы смотрим, где нога находится в анимации, чтобы луч всегда был строго под ней.
Берём позицию кости стопы c помощью ноды get transform - bone . (например, ik_foot_l - на скриншоте их нет - их эпики указывают чуть позже ) по осям X и Y.
К оси Y можно добавить небольшое смещение (например, +5), чтобы сдвинуть "сенсор" луча из-под щиколотки под подушечку стопы. Это делает постановку ноги более естественной.
Присоединяем это к ноде ADD и Substract по осям X ,Y
2. Рассчитываем высоту (Z)
Чтобы луч гарантированно находил землю на любом рельефе, мы задаем ему начальную и конечную точки, привязанные к высоте (Root).
Начальная точка (Start):
Берем данные с рутовой кости с помощью ноды get transform - bone
Присоединяем это к ноде ADD и Substact по осям Z
в ноде Add во вкладке B ставим 30 для оси Z
и в ноде Substract для оси Z , во вкладке B ставим 50 )
Зачем добавляем 30 ?: В анимации нога может "войти" в склон или ступеньку. Если начать луч изнутри объекта, он сработает неправильно.Решение: Высота (Root.Z) + 30 юнитов. Мы принудительно поднимаем начальную точку высоко над землёй, гарантируя, что луч всегда стартует из пустого пространства.
Зачем мы ставим 50 в Substract ?
Проблема: Если персонаж спускается со склона, земля может оказаться ниже, чем обычно. Короткий луч может "не дотянуться" до неё.Решение: Высота (Root.Z) - 50 юнитов. Мы делаем луч заведомо длиннее, чем нужно, чтобы он, как длинный "щуп", гарантированно пересёк любую поверхность под ногами.
3. Собираем все вместе
Собираем Start: (Стопа.X, Стопа.Y + 5, Таз.Z + 30)
Их собираем через ноду Add
Собираем End: (Стопа.X, Стопа.Y + 5, Таз.Z - 50)
Их собираем через ноду Substract
Запускаем Sphere Trace By Channel из Start в End с небольшим радиусом (например, 3.0) для более надёжного контакта.
4. Возвращаем результат
Если луч нашёл поверхность, мы берём результат столкновения (Hit Location ) и передаем его дальше (в Return Node)
Идем в сам риг
Логика включения и выключения IK
проверяем для начала должны ли мы включать ik или нет ( это делается через ноду Branch ) у эпиков если персонаж в воздухе то логика ik не работает ( значение для булевной переменной мы указываем в анимационном блюпринте персонажа и оставим это за рамками этих заметок)
Если нет :Set ZOffset_L_Target: В переменную для левой ноги принудительно записывается 0.0.
Set ZOffset_R_Target: В переменную для правой ноги также записывается 0.0.
Итог ветки: IK-смещения обнуляются, и ноги персонажа просто следуют за основной анимацией, свободно болтаясь в воздухе. это мы используем когда персонаж в воздухе ( в прыжке)
Если же наш персонаж не падает то
Путь True (Персонаж на земле)
Что происходит: Если Should Do IKTrace истинно, выполняется верхняя ветка.
FootTrace (для левой ноги): Запускается ваша локальная функция трассировки для левой ноги (ik_foot_l).( обратите здесь во вкладке Name мы указываем название кости для которой делается line trace
Set ZOffset_L_Target: Результат трассировки (Offset.Z — вертикальное смещение) сохраняется в переменную для левой ноги.
FootTrace (для правой ноги): То же самое происходит для правой ноги.
Set ZOffset_R_Target: Результат сохраняется в переменную для правой ноги.
Важно все расчет мы делаем для специальных костей с приставкой ik ( эти кости стандартно идут в unreal манекене)
Alpha Interpolate (Сглаживание-)
Что делает: Этот узел работает как "доводчик". Он не позволяет значению мгновенно измениться. Вместо этого он плавно "ведёт" текущее значение к целевому с заданной скоростью.
Value: Сюда подаётся целевое смещение (например, -10 см), рассчитанное на предыдущем шаге с помощью Line Trace.
Interp Speed Increasing/Decreasing: Это скорость сглаживания. Вы можете задать разную скорость для движения вниз и вверх, чтобы, например, нога "вдавливалась" в землю медленнее, чем отрывалась от неё.
Как работает вся цепочка
Логика одинакова для левой (_L) и правой (_R) ноги:
Получаем цель: Код берёт переменную Get ZOffset_L_Target, в которой хранится "сырое" смещение для левой ноги.
Сглаживаем значение: Узел Alpha Interpolate вычисляет новое, сглаженное значение, плавно двигаясь к цели.
Сохраняем результат: Это сглаженное значение сохраняется в финальную переменную Set ZOffset_L.
Итог и назначение
Этот код — "амортизатор" для системы IK.
Без этого сглаживания, при ходьбе по неровностям, ноги персонажа мгновенно "прыгали" бы на новую высоту каждого камня. Это выглядело бы очень резко, неестественно и "дёргано".
Коррекция положения таза
Get ZOffset_L и Get ZOffset_R — получаем значения смещения по оси Z (высоты) для левой и правой ноги.
Less (A < B) — проверяет, меньше ли смещение левой ноги, чем правой.→ True: левая нога ниже → использовать ZOffset_L → False: правая нога ниже или на том же уровне → использовать ZOffset_R
If (Select node) — выбирает одно из двух значений в зависимости от результата Less: True: передаёт ZOffset_L False: передаёт ZOffset_R
Set ZOffset_Pelvis — устанавливает смещение таза на наименьшее значение из двух стоп.
Что это значит на практике?
Допустим:
Левая стопа опирается на ступеньку (-15 см),
Правая — на полу (0 см).
Если бы таз не двигался вниз — левая нога бы "вытянулась", нарушив реалистичность. Этот код опускает таз вниз до уровня левой стопы, чтобы обе ноги оставались в пределах нормальной длины.
Смешаем кости с помощью полученных оффсетов
Modify Transforms (Модификация трансформаций)
Что это: Это узел в Control Rig, который позволяет добавить смещение к текущей трансформации кости.
Name : тут указываем какую кость мы хотим сместить
Нода Get ZOffset_L содержить наше смешение кости + сглаживание котрое мы добавили в прошлвх шагах с помощью Alpha interpolate
Mode: Additive Global: Этот режим означает, что смещение будет добавлено к текущей позиции кости в глобальных координатах мира.
Full Body IK (Инверсная кинематика всего тела)
Full Body IK (Инверсная кинематика всего тела)
Это IK (Solver), который изменяет положение целой иерархии костей для достижения заданных целей ( короче говоря двигает цепочки костей) .
pelvis (таз) — указывается началом цепочки . Solver будет изгибать всё, что "ниже" таза (ноги), и может даже слегка корректировать то, что "выше" (позвоночник), чтобы сохранить баланс( на самом деле этот солвер може тдвигать все тело) .
Effectors (Цели для IK)
Тут указываем
1: Кость foot_l (левая стопа) должна переместиться в позицию и принять трансформы от "виртуальной" кости IK_foot_L.
: Кость foot_r (правая стопа) должна сделать то же самое, ориентируясь на IK_foot_R.
Позиции IK_foot_L и IK_foot_R — берем через Get transform - Bone
Вывод : мы измеряем расстояние до земли - если оно меняется - мы подстраиваем положение ног под эти изменения и корректируем таз с учетом этого , после этого создаем full body ik solver и кидаем трансформы c наших ik костей на эффекторы этого солвера и указываем уже кости foot_r and foot_l скелета как цель для этих эффекторов.
Мой телеграм канал.