Animation Rigging — процедурная анимация и IK
TwoBone IK, Aim Constraint, Multi-Parent — наложение процедурных слоёв на готовую анимацию.
Стандартный Animator проигрывает записанные анимации. Что делать, если:
- Персонаж должен смотреть на динамическую цель (на врага, на мышиный курсор).
- Рука должна удерживать ручку двери, пока та поворачивается.
- Стопа должна корректно касаться неровного пола (foot IK).
Animation Rigging пакет (com.unity.animation.rigging) даёт процедурные constraint’ы, которые
накладываются поверх обычной анимации Animator’а.
Главная идея — riggable layer
Структура:
Player (Animator)
└── Hips (root bone)
├── Spine → Chest → Neck → Head
├── LeftShoulder → ...
└── RightShoulder → ...
Player → RigBuilder (компонент)
└── Rig (GameObject)
└── HeadAimConstraint (узел)
constrained_object: Head
source_objects: [Target]
weight: 1.0
RigBuilder собирает все constraint’ы и применяет их после базовой анимации Animator’а.
Constraint’ы — отдельные GameObject’ы с компонентом-логикой.
Анимационные пайплайны типа Three.js + IK-solver или Spline-based rigging в Blender. Только в Unity это runtime, real-time, на каждый кадр.
Animation Rigging не заменяет Animator — она дополняет. Animator говорит “правая рука вот тут”, Rigging говорит “и доводим до target”. Веса позволяют смешивать процедурное с записанным.
Установка
- Package Manager → Animation Rigging → Install.
- На GameObject с Animator → Add Component → Rig Builder.
- Дочерним к нему — Empty GameObject “Rig” → добавьте Rig компонент.
- В Rig Builder указываете “Rig” в Layers list.
- К Rig добавляете constraint-узлы как детей.
TwoBone IK — рука дотягивается до точки
Самый частый IK. Цель — указать “куда тянется кисть”, решатель находит положение локтя.
- На Rig добавьте Empty GameObject “RightArmIK”.
- Add Component → Two Bone IK Constraint.
- В Inspector:
- Root: правое плечо bone
- Mid: правый локоть bone
- Tip: правая кисть bone
- Target: пустой объект (куда тянется кисть)
- Hint: пустой объект (направление к локтю — чтобы решатель знал, “куда сгибать”)
Двигаете Target — кисть автоматически дотягивается, локоть гнётся естественно.
public class GrabHandle : MonoBehaviour
{
[SerializeField] private Transform ikTarget;
[SerializeField] private TwoBoneIKConstraint armIK;
public void GrabAt(Transform doorHandle) {
ikTarget.position = doorHandle.position;
ikTarget.rotation = doorHandle.rotation;
StartCoroutine(BlendWeight(0f, 1f, 0.3f)); // плавно включаем
}
private IEnumerator BlendWeight(float from, float to, float duration) {
float t = 0;
while (t < duration) {
t += Time.deltaTime;
armIK.weight = Mathf.Lerp(from, to, t / duration);
yield return null;
}
armIK.weight = to;
}
}
weight = 1.0 — IK полностью активен. weight = 0 — оригинальная анимация Animator. Между 0 и 1
— смесь. Это даёт smooth “хватаемся за ручку” анимацию.
Aim Constraint — смотреть на цель
Голова персонажа следит за target’ом:
- На Rig добавьте “HeadAim”.
- Multi-Aim Constraint.
- Constrained Object: Head bone.
- Source Objects: array с одним target’ом (или несколькими с весами).
- Aim Axis: forward Z обычно.
- World Up Type: ObjectRotationUp → object: Head (чтобы голова не “переворачивалась”).
- Limits: ±60° (нельзя голову повернуть на 180° — это не сова).
[SerializeField] private MultiAimConstraint headAim;
[SerializeField] private Transform aimTarget;
private void Update() {
// Цель = курсор мыши через raycast
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, 50f)) {
aimTarget.position = hit.point;
}
}
Теперь голова персонажа следит за курсором в реальном времени, без записанной анимации “повернуть голову к точке”.
Multi-Parent Constraint — две руки на одном объекте
Сценарий: персонаж несёт меч обеими руками. Анимация ходьбы написана для одной руки; другую нужно процедурно держать на рукояти.
- На Rig → “LeftHandToSword”.
- Multi-Parent Constraint.
- Constrained Object: левая кисть bone.
- Source Objects: [SwordHandle_Left] (target на мече, где должна быть левая ладонь).
- Constrained Properties: Position + Rotation.
Теперь куда бы ни двигалась правая рука (с мечом), левая всегда “прилипает” к нужной точке меча.
Chain IK — для длинных цепей (хвост, щупальце)
TwoBoneIKConstraint — 3 кости. Для длинной цепи (4+):
- Chain IK Constraint — для произвольного количества костей. Алгоритм FABRIK.
Применение: щупальца, хвосты, гибкие животные.
Override Transform — full control одной кости
Если нужно полностью контролировать позицию/поворот конкретной bone, минуя Animator:
- Override Transform Constraint.
- Источник — Transform-объект на сцене.
- Целевая bone полностью копирует его трансформ.
Полезно для:
- Прикрепления оружия к hand bone (или используйте Bone Attachment-pattern с child GameObject).
- “Заморозить” bone в определённом положении.
Damped Transform — задержка / “пружина”
Constraint, где bone догоняет target с задержкой:
- Damped Transform Constraint.
- Damp Position / Damp Rotation — насколько отстаёт.
Применение: серёжки, болтающиеся аксессуары, длинные волосы.
Performance
Каждый constraint — это per-frame compute. Десятки constraint’ов на одном персонаже могут заметно стоить. Профайлите.
Особенно дорого:
- Multi-Aim с большим количеством source-objects.
- Chain IK с длинной цепью.
- Override Transform на каждой bone.
Оптимизация: выключайте RigBuilder.enabled = false для off-screen / далёких персонажей.
Workflow: смешиваем готовое и процедурное
Классический подход:
1. Animator проигрывает Walk-Run blend tree → базовая поза.
2. Rig Builder применяет:
- Head Aim → голова к врагу
- Left Hand IK → ладонь на оружии (если двуручное)
- Foot IK → стопы корректно стоят на лестнице
3. Окончательная поза рендерится.
Игрок видит: персонаж естественно идёт по сцене, смотрит на врага, идёт по лестнице корректно ставя ноги — без 50 записанных анимаций для разной геометрии.
Animator (Humanoid) имеет built-in OnAnimatorIK callback с SetIKPosition/SetIKWeight —
достаточно для базового Foot IK. Animation Rigging нужен, если хотите более кастомный workflow
или не-humanoid скелет (например, существа на 4 ногах).
Когда не нужен Animation Rigging
- Если все нужные движения уже в записанной анимации — не добавляйте лишний компонент.
- На массовых NPC в open-world — слишком дорого; используйте упрощённый Humanoid IK.
- В 2D-проектах — там 2D Animation package и Sprite Skin.