# 5. Animation Rigging and Script IK Part of [[Animation]]. Prev: [[4.Layers Masks Root Motion and Events]]. Next: [[6.Worked Example Locomotion Look-At and Hand IK]]. **Docs:** Animation Rigging package manual/API **6.6.0** — Rigging Workflow; Constraint Components; Two Bone IK; Multi-Aim Constraint; `RigBuilder`, `Rig`, `TwoBoneIKConstraint` / `TwoBoneIKConstraintData`. Script IK: Scripting API 6000.5 — `MonoBehaviour.OnAnimatorIK`, `Animator.SetIKPosition`, `SetLookAtPosition`, etc. Install: Package Manager → **Animation Rigging** (`com.unity.animation.rigging`). Use the version Package Manager resolves for your Editor. Types below were verified against the **6.6.0** doc set (Unity 6 line). ## 5.1 Two IK systems — when to use which | | **OnAnimatorIK** (built-in) | **Animation Rigging** (package) | |---|---|---| | Avatar | Humanoid only | Any hierarchy (Humanoid or Generic) | | Setup | Enable **IK Pass** on the Animator layer; script on the **same GameObject** as Animator | `RigBuilder` on Animator root + `Rig` child + constraint components | | Goals | Hands, feet, body look-at (`AvatarIKGoal`, look-at weights) | TwoBoneIK, ChainIK, MultiAim, MultiParent, … | | Weighting | Per-goal weights each IK pass | `constraint.weight`, `rig.weight`, RigBuilder layers | | Timeline / graph | Animator IK pass | Constraints run as Animation Jobs appended after Animator evaluation | | Best for | Quick humanoid hand/foot plant and look-at | Gameplay IK, props, non-humanoid, multi-constraint stacks | You can combine them carefully, but prefer **one owner** per bone to avoid fighting. ## 5.2 Rigging Workflow (verified) From the package **Rigging Workflow** manual: 1. **Animator** on the character root (required). 2. Add **Rig Builder** on that **same** root (`[RequireComponent(typeof(Animator))]`). 3. Create a child GameObject (e.g. `Rig_Setup`) **beside** the skeleton root (not inside the bone hierarchy) and add **Rig**. 4. On Rig Builder → **Rig Layers** → assign the Rig component. 5. Under the Rig, add children with **constraint** components (rig elements). Put Target / Hint effectors as children of those elements. 6. Evaluation order follows hierarchy depth-first (`GetComponentsInChildren` order). Also useful: **Bone Renderer** (editor visualization), **Rig Effectors** (gizmo picks), **Rig Transform** on manipulation pivots that constraints do not reference but you still move. `Rig.weight` (0..1) scales the whole rig. `RigBuilder.layers` holds the stack; enable/disable layers independently. ```csharp using UnityEngine; using UnityEngine.Animations.Rigging; [RequireComponent(typeof(RigBuilder))] public sealed class RigWeightPulse : MonoBehaviour { [SerializeField] Rig rig; [SerializeField] float weight = 1f; void LateUpdate() { if (rig != null) rig.weight = Mathf.Clamp01(weight); } } ``` Manual evaluation pattern from `RigBuilder` API docs (when you disable the component and step the graph yourself): ```csharp using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations.Rigging; [RequireComponent(typeof(RigBuilder))] public sealed class ManualRigEvaluator : MonoBehaviour { RigBuilder _rb; void OnEnable() { _rb = GetComponent<RigBuilder>(); _rb.enabled = false; if (_rb.Build()) _rb.graph.SetTimeUpdateMode(DirectorUpdateMode.Manual); } void LateUpdate() { _rb.Evaluate(Time.deltaTime); } } ``` Most gameplay uses the default automatic evaluation (`RigBuilder` enabled) — prefer that until you need custom ordering. ## 5.3 Constraint catalog (package) Documented built-ins (Constraint Components manual): Blend, Chain IK, Damped Transform, Multi-Aim, Multi-Parent, Multi-Position, Multi-Referential, Multi-Rotation, Override Transform, Twist Chain, Twist Correction, **Two Bone IK**. This fundamentals set deep-dives **TwoBoneIK** and **MultiAim**. ## 5.4 Two Bone IK Inspector / data (manual + `TwoBoneIKConstraintData` API): | Property | Purpose | |---|---| | `weight` | Overall constraint weight | | `data.root` / `mid` / `tip` | Limb chain (upper arm → forearm → hand, or thigh → shin → foot) | | `data.target` | Desired tip transform | | `data.hint` | Optional pole vector (elbow/knee bend direction) | | `data.targetPositionWeight` / `targetRotationWeight` | Reach vs align tip rotation | | `data.hintWeight` | Hint influence | | `data.maintainTargetPositionOffset` / `maintainTargetRotationOffset` | Keep authored tip–target offsets | Context menu: **Auto Setup from Tip Transform** — assigns Tip, then creates Target + Hint under the Rig. ```csharp using UnityEngine; using UnityEngine.Animations.Rigging; /// Drives a hand IK target toward a world-space grip point. public sealed class HandIkTargetDriver : MonoBehaviour { [SerializeField] TwoBoneIKConstraint handIk; [SerializeField] Transform gripPoint; [SerializeField] float enterSpeed = 8f; Transform _target; float _w; void Awake() { if (handIk == null) return; _target = handIk.data.target; } public void SetGrabbing(bool grabbing) => _w = grabbing ? 1f : 0f; void LateUpdate() { if (handIk == null || _target == null || gripPoint == null) return; _target.SetPositionAndRotation(gripPoint.position, gripPoint.rotation); handIk.weight = Mathf.MoveTowards(handIk.weight, _w, enterSpeed * Time.deltaTime); } } ``` ## 5.5 Multi-Aim Constraint Rotates a **Constrained Object** to face one or more **Source Objects** (weighted sum of aim rotations — package manual notes this differs from some DCC tools). Typical use: head / torso look-at, turret aim, eyes. Key inspector properties (manual): Weight; Constrained Object; Aim Axis; Up Axis; World Up Type (`None`, `Scene Up`, `Object Up`, `Object Up Rotation`, `Vector`); World Up Axis / Object; Source Objects list; Maintain Rotation Offset; Offset; Constrained Axes; Min/Max Limit. ```csharp using UnityEngine; using UnityEngine.Animations.Rigging; /// Blends MultiAim weight when a look target exists. /// Source object transforms are usually assigned in the Inspector. public sealed class MultiAimWeightDriver : MonoBehaviour { [SerializeField] MultiAimConstraint aim; [SerializeField] Transform sourceTransform; // the aim target effector [SerializeField] float speed = 6f; Transform _look; float _w; public void SetLookTarget(Transform t) { _look = t; _w = t != null ? 1f : 0f; } void LateUpdate() { if (aim == null) return; if (_look != null && sourceTransform != null) sourceTransform.position = _look.position; aim.weight = Mathf.MoveTowards(aim.weight, _w, speed * Time.deltaTime); } } ``` > [!note] Scripted MultiAim sources > Inspector **Source Objects** weighting is verified from the manual. Mutating the weighted transform list from C# at runtime is ***(unverified)*** in this note set — prefer moving a single pre-assigned source effector transform (as above). ## 5.6 Classic script IK (`OnAnimatorIK`) Requirements (Scripting API): 1. Avatar **Humanoid**. 2. Animator Controller **layer** has **IK Pass** enabled. 3. Animator enabled and playing. 4. Script with `OnAnimatorIK` on the **same GameObject** as the Animator. ```csharp using UnityEngine; [RequireComponent(typeof(Animator))] public sealed class HumanoidLookAndHandIk : MonoBehaviour { [SerializeField] Transform lookAt; [SerializeField] Transform rightHandGoal; [SerializeField, Range(0f, 1f)] float lookWeight = 1f; [SerializeField, Range(0f, 1f)] float handWeight = 0f; Animator _anim; void Awake() => _anim = GetComponent<Animator>(); void OnAnimatorIK(int layerIndex) { if (lookAt != null) { _anim.SetLookAtWeight(lookWeight); _anim.SetLookAtPosition(lookAt.position); } else { _anim.SetLookAtWeight(0f); } if (rightHandGoal != null) { _anim.SetIKPositionWeight(AvatarIKGoal.RightHand, handWeight); _anim.SetIKRotationWeight(AvatarIKGoal.RightHand, handWeight); _anim.SetIKPosition(AvatarIKGoal.RightHand, rightHandGoal.position); _anim.SetIKRotation(AvatarIKGoal.RightHand, rightHandGoal.rotation); } else { _anim.SetIKPositionWeight(AvatarIKGoal.RightHand, 0f); _anim.SetIKRotationWeight(AvatarIKGoal.RightHand, 0f); } } } ``` ## 5.7 Authoring checklist (Rigging) ``` CharacterRoot Animator + RigBuilder ├── SkeletonRoot (hips … bones) └── Rig_Setup Rig (assigned on RigBuilder layer) ├── HeadAim MultiAimConstraint → constrained = head bone │ └── LookTarget (empty effector; sources list points here) └── RightHandIK TwoBoneIKConstraint (root/mid/tip = arm bones) ├── RH_Target └── RH_Hint ``` 1. Auto Setup from Tip for hands/feet. 2. Position Hint in front of elbow/knee. 3. Animate or script `Rig.weight` / constraint `weight` for blend-in. 4. After hierarchy changes, ensure RigBuilder rebuilds (disable/enable or call `Build()` if you were in manual mode). ## 5.8 Verified vs unverified **Verified:** RigBuilder + Rig + Constraints workflow and hierarchy rules; constraint list; TwoBoneIK properties and `TwoBoneIKConstraintData` fields; `TwoBoneIKConstraint.weight` / `.data`; MultiAim inspector properties and World Up Type values; `Rig.weight`; `RigBuilder.Build` / `Evaluate` / `graph` / manual evaluation example; `OnAnimatorIK` requirements and SetIK*/SetLookAt* APIs. **Unverified:** runtime mutation of MultiAim source weighted lists; interaction order when both OnAnimatorIK and Animation Rigging write the same bone; exact Package Manager version string on 6000.5 vs 6000.6. **Not compiled:** all scripts in this part.