# 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.