Animation Rigging

Unity's Animation Rigging package allows you to set up rigs that dynamically modify your animations with things like Multi-Parent Constraints and Inverse Kinematics (which works on both Generic and Humanoid Rigs where Unity's inbuilt IK system only works on Humanoids).

The official Working with Animation Rigging tutorial explains how to use it. Using it with Animancer is no different from using it with Animator Controllers.

Click here to see some of its features.

Damped Transform

Multi Parent Constraint

Inverse Kinematics

Limitations

Resetting Properties

The way the Animation Rigging system reads properties like the Weight of its constraint components causes them to be treated like animated properties, meaning that calling Animator.Rebind will reset those properties to their starting values.

Unfortunately, Animator.Rebind gets called every time a Playable is connected or disconnected which happens frequently in Animancer depending on the AnimancerGraph.KeepChildrenConnected property:

KeepChildrenConnected Event Common Example
true
Default for Generic Rigs
A state's layer is set. Playing an animation that hasn't been played on that character yet will create a new state for it and connect that state to a layer (usually the default base layer).
false
Default for Humanoid Rigs
A state's layer is set or its Weight changes to or from 0. Playing an animation sets its Weight to 1 (or fades it in) which connects it to its layer and stopping an animation sets its Weight to 0 which disconnects it from its layer.

This isn't a problem for Animator Controllers because they simply don't allow their structure to be changed at runtime.

This issue can be avoided by using a PlayableOutputRefresher:

public class PlayableOutputRefresherExample : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private Rig _Rig;

    // A field to store it in.
    private PlayableOutputRefresher _OutputRefresher;

    protected virtual void OnEnable()
    {
        // Initialize on startup.
        _OutputRefresher = new(_Animancer);
    }

    public void SetWeight(float weight)
    {
        // Change something that would be reset.
        _Rig.weight = weight;
        
        // Then call this afterwards.
        _OutputRefresher.Refresh();
    }
}

IK Targets

The position and rotation of Target and Hint objects used by the Inverse Kinematics system from the Animation Rigging package are affected by the same resetting effect explained above, but fortunately it can be avoided by ensuring those objects are not children of the character's Animator component. The Hierarchy should look something like this (the object names list their components):

Paused Graph

Normally, Animancer creates a PlayableGraph and the Animation Rigging system creates another one which reads its inputs from the previous one. This allows it to avoid interfering with the main animation system so it can work the same regardless of whether the primary graph is managed by an Animator Controller or Animancer or any other system that uses the Playables API.

Unfortunately, manually calling PlayableGraph.Evaluate (like in the Update Rate sample) only evaluates that graph on its own and there doesn't seem to be any way to make them both update in sequence as they would during a regular animation update. This causes the Animation Rigging system to completely fail if you try to manually evaluate the graph.

This can be solved by initializing Animancer to use the same PlayableGraph as the Animation Rigging system with a script like this:

using Animancer;
using UnityEngine;
using UnityEngine.Animations.Rigging;

[DefaultExecutionOrder(1000)]// Awake after the RigBuilder creates its PlayableGraph.
public class AnimancerUseRiggingGraph : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private RigBuilder _RigBuilder;

    protected virtual void Awake()
    {
        var graph = new AnimancerGraph(_RigBuilder.graph);
        _Animancer.InitializePlayable(graph);
    }
}

Then you can simply call _Animancer.Evaluate() normally and it will evaluate both Animancer and the Animation Rigging system properly.