Quick answer: The most common cause is a missing or misconfigured Rig Builder component on the root Animator GameObject. The Rig Builder must reference the Rig layer that contains your constraints. Without this connection, constraints exist in the hierarchy but are never evaluated by the animation pipeline.
Here is how to fix Unity animation rigging constraint not working. You added a Multi-Aim Constraint or Two Bone IK to your character rig in Unity, hit Play, and nothing happens. The bones do not move. The constraint appears in the Inspector with all its fields filled in, but at runtime the character animates exactly as if the constraint does not exist. This is one of the most disorienting issues in the Animation Rigging package because there are no errors, no warnings — just silent failure. Here is how to fix it.
The Symptom
You have installed the Animation Rigging package from the Unity Package Manager. You created a Rig GameObject as a child of your character, added a constraint component (such as Multi-Aim Constraint, Two Bone IK Constraint, or Override Transform), and assigned the relevant bone references. In the Scene view, you might even see gizmo indicators showing the constraint targets.
But when you enter Play mode, the constraint has zero effect. The character plays its Animator clips normally, completely ignoring the constraint. If you have a look-at target moving around the scene, the character’s head does not follow it. If you set up a Two Bone IK for a hand reaching toward an object, the hand stays locked to the animation clip position.
There are no console errors. The Animator plays. The constraint component is enabled. Everything appears correct on the surface, which makes this particularly frustrating to debug.
What Causes This
1. Missing Rig Builder component. This is the most common cause. The Animation Rigging system requires a RigBuilder component on the same GameObject as the Animator. The Rig Builder is the bridge between Unity’s Playable Graph and your constraint hierarchy. Without it, constraints are just MonoBehaviours sitting in the hierarchy doing nothing. Many tutorials mention adding the Rig layer but skip the crucial step of adding the Rig Builder or forget to show that it must reference the Rig.
2. Rig layer not assigned to the Rig Builder. Even if the Rig Builder exists, its Rig Layers list must explicitly contain a reference to your Rig GameObject. If the list is empty or the Rig is not in it, the builder has nothing to build. This commonly happens when you duplicate a character prefab and the serialized reference breaks.
3. Weight is zero. Both the Rig layer and individual constraints have a weight property that ranges from 0 to 1. If either weight is zero, the constraint produces no output. The Rig weight defaults to 1, but constraint weights can default to 0 in some versions of the package, especially after a package update or when the constraint is added via script.
4. Null or broken bone references. Every constraint requires at least a Constrained Object (the bone being driven) and usually one or more Source Objects (the targets). If any of these fields is None, the constraint cannot evaluate. This happens frequently when skeleton bones are renamed in the DCC tool and reimported, or when a prefab variant loses its override references.
5. Evaluation order conflicts with the Animator. Animation Rigging constraints run as a post-process on the Animator’s Playable Graph. If your Animator Controller writes to the same bones every frame with full weight, and the Rig layer weight or constraint weight is too low, the Animator effectively overwrites the constraint output. This is especially problematic when using Apply Root Motion or when an animation clip explicitly keys the constrained bone.
The Fix
Step 1: Add and configure the Rig Builder. Select the root GameObject that has your Animator component. Add a RigBuilder component if one does not already exist. Then assign your Rig layer to the Rig Layers list.
using UnityEngine;
using UnityEngine.Animations.Rigging;
public class RigSetup : MonoBehaviour
{
[SerializeField] private Rig rig;
void Start()
{
// Ensure the RigBuilder exists on the Animator root
var builder = GetComponent<RigBuilder>();
if (builder == null)
{
builder = gameObject.AddComponent<RigBuilder>();
Debug.Log("Added missing RigBuilder component");
}
// Add the rig layer if not already present
if (!builder.layers.Contains(new RigLayer(rig)))
{
builder.layers.Add(new RigLayer(rig, true));
builder.Build();
Debug.Log("Rebuilt RigBuilder with rig layer");
}
}
}
The hierarchy should look like this: your character root has the Animator and RigBuilder. Directly beneath it is a Rig GameObject with the Rig component. Beneath the Rig are your individual constraint GameObjects. The Rig must be a child of the Animator root — if it is placed elsewhere in the scene hierarchy, the builder cannot find the bone transforms.
Step 2: Verify weights are non-zero. Select your Rig GameObject and check that its Weight slider is set to 1. Then select each constraint and confirm its Weight is also 1. You can verify this programmatically at runtime:
using UnityEngine;
using UnityEngine.Animations.Rigging;
public class ConstraintDebugger : MonoBehaviour
{
void Start()
{
// Check all rigs under this Animator
var rigs = GetComponentsInChildren<Rig>();
foreach (var rig in rigs)
{
Debug.Log($"Rig '{rig.name}' weight: {rig.weight}");
if (rig.weight < 0.01f)
Debug.LogWarning($"Rig '{rig.name}' weight is effectively zero!");
}
// Check individual constraint weights
var constraints = GetComponentsInChildren<IRigConstraint>();
foreach (var constraint in constraints)
{
var mb = constraint as MonoBehaviour;
if (mb == null) continue;
var weightProp = mb.GetType().GetProperty("weight");
if (weightProp != null)
{
float w = (float)weightProp.GetValue(mb);
Debug.Log($"Constraint '{mb.name}' weight: {w}");
}
}
}
}
Step 3: Re-assign broken bone references. Open each constraint in the Inspector. Look for any field that shows None (Transform) where a bone should be assigned. Common fields include Constrained Object, Source Objects, Root, Mid, Tip (for Two Bone IK), and Aim Axis settings.
using UnityEngine;
using UnityEngine.Animations.Rigging;
public class AutoAssignBones : MonoBehaviour
{
[SerializeField] private MultiAimConstraint aimConstraint;
[SerializeField] private Transform headBone;
[SerializeField] private Transform lookTarget;
void Awake()
{
// Validate bone references before Play mode
if (aimConstraint.data.constrainedObject == null)
{
Debug.LogError("Constrained object is null - assigning head bone");
aimConstraint.data.constrainedObject = headBone;
}
// Assign source objects (the look-at target)
var sources = aimConstraint.data.sourceObjects;
if (sources.Count == 0 || sources[0].transform == null)
{
sources.Clear();
sources.Add(new WeightedTransform(lookTarget, 1f));
aimConstraint.data.sourceObjects = sources;
Debug.Log("Reassigned look target as source object");
}
// Rebuild the rig to pick up the changes
var builder = GetComponentInParent<RigBuilder>();
builder?.Build();
}
}
After fixing references, you must rebuild the Playable Graph. In the editor, exiting and re-entering Play mode does this automatically. At runtime, call RigBuilder.Build() after modifying any constraint data.
Evaluation Order and Animator Conflicts
Animation Rigging constraints are evaluated as a post-process after the Animator evaluates its clips and state machine. This means the Animator runs first, writes bone transforms, and then constraints modify those transforms. If a constraint appears to have no effect even with correct setup, the Animator clip may be overwriting the bone every frame.
To test this, temporarily disable the Animator Controller by setting the Animator’s runtimeAnimatorController to null. If the constraint suddenly works, the problem is that your animation clip is keying the constrained bone with full weight.
using UnityEngine;
public class AnimatorConflictTest : MonoBehaviour
{
private Animator animator;
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
// Press Space to toggle the Animator off for testing
if (Input.GetKeyDown(KeyCode.Space))
{
animator.enabled = !animator.enabled;
Debug.Log($"Animator enabled: {animator.enabled}");
}
}
}
The solution to Animator conflicts is to use an Animation Rigging layer with higher priority, or to create an override animation clip on a higher-priority Animator layer that does not key the constrained bone. You can also use an empty avatar mask that excludes the constrained bone from the base animation layer.
Runtime Rig Building
If you are adding constraints at runtime (for example, dynamically attaching IK targets to a character), you must call RigBuilder.Build() after setting up the constraint data. The Playable Graph is constructed once when Play mode starts; adding new constraints without rebuilding means they are invisible to the graph.
using UnityEngine;
using UnityEngine.Animations.Rigging;
public class RuntimeConstraintAdder : MonoBehaviour
{
[SerializeField] private RigBuilder rigBuilder;
[SerializeField] private Transform rigTransform;
[SerializeField] private Transform targetBone;
[SerializeField] private Transform sourceTarget;
public void AddAimConstraintAtRuntime()
{
// Create constraint GameObject under the Rig
var constraintGO = new GameObject("DynamicAim");
constraintGO.transform.SetParent(rigTransform);
// Add and configure the constraint
var aim = constraintGO.AddComponent<MultiAimConstraint>();
aim.data.constrainedObject = targetBone;
aim.weight = 1f;
var sources = new WeightedTransformArray(1);
sources[0] = new WeightedTransform(sourceTarget, 1f);
aim.data.sourceObjects = sources;
// Critical: rebuild the playable graph
rigBuilder.Build();
Debug.Log("Dynamic constraint added and rig rebuilt");
}
}
Why This Works
The Animation Rigging package operates through Unity’s Playable Graph system. When the game starts, the RigBuilder constructs a playable graph that includes nodes for each constraint in the Rig Layers list. These nodes run after the Animator’s clip playback nodes, which is how constraints can modify bone transforms that are already being driven by animation clips.
Without the Rig Builder, there is no playable graph for constraints — they are just components with data. Without a valid Rig Layer reference, the builder constructs an empty graph. Without non-zero weights, the constraint nodes evaluate but their output is multiplied by zero. And without valid bone references, the constraint nodes have no transforms to read from or write to.
Each step in the fix addresses one link in this chain. The system is designed to fail silently rather than throw exceptions, which is why these issues are so hard to diagnose without knowing the architecture.
"The Rig Builder is the one piece everyone forgets. The constraint is not self-contained. It needs the builder to inject it into the Playable Graph, and the builder needs to live on the Animator root."
Related Issues
If your constraints work in the Editor but break in a build, check that the Animation Rigging package is included in your build configuration and that the Burst compiler is not stripping the constraint jobs. For IK constraints that overshoot or oscillate, adjusting the Maintain Offset and Chain Rotation Weight settings usually stabilizes them. If constraints snap instead of blending smoothly, animate the weight property over time using DOTween or a coroutine rather than setting it to 1 instantly.