States

When you play an AnimationClip, Animancer creates and returns an AnimancerState which you can use to control it and keep track of its progress. Then if you play the same animation again later, it will reuse that same state. For example:

void PlayAnimation(AnimancerComponent animancer, AnimationClip clip)
{
    AnimancerState state = animancer.Play(clip);
    state.Time = ...
    state.NormalizedTime = ...
    state.Speed = ...
    state.Events(this).OnEnd = ...
}

There are various other ways of accessing and creating states and the Performance section explains their general efficiency implications:

Code Description
var state = animancer.States.Current;
This property stores the state that was most recently returned by the Play method. If you're using multiple Layers, this property refers to the base layer (Layer 0).
var state = animancer.Layers[x].CurrentState;
This property stores the state that was most recently returned by the Play method of Layer x.
var state = animancer.States[clip];
var state = animancer.States[key];

Returns the state registered with the given Key.

Throws a KeyNotFoundException if no such state exists (use TryGet to avoid that).
animancer.States.TryGet(clip, out AnimancerState state);
animancer.States.TryGet(key, out AnimancerState state);
If a state is already registered with the given Key, this method assigns it to the state out Parameter and returns true. Otherwise the state will be null and the method returns false.
var state = animancer.States.GetOrCreate(clip);
If a state for the clip already exists, this method returns it. Otherwise it creates and returns a new one. The Play(clip) method uses this internally.
var state = animancer.States.Create(key, clip);
Creates a new state even if one already existed for that animation. Note that each state must have a different Key or it will throw an ArgumentException.
var state = new ClipState(clip);
Creates a new state without giving it a Key.
var state = transition.CreateState();
transition.Apply(state);
var state = transition.CreateStateAndApply();

Creates a new state from the details defined in a Transition.

Note that some details are not applied by the initial CreateState such as the Start Time, Speed, and Events. Those values are instead assigned by Apply which is called as part of the regular animancer.Play(transition); even when it reuses an existing state.
animancer.States.Destroy(clip);
If a state for the clip exists, this method destroys it and returns true. Otherwise it returns false.
state.Destroy();
Destroys a specific state you already have a reference to.

The Fine Control samples demonstrate how you can manipulate animation states in more detail.

Performance

Creating a state and connecting it to the Playable Graph takes a bit of time, just like any other operation. In the vast majority of cases this cost is so small that it's not worth considering, so you should just create states wherever is most convenient. This is why the most common way of using Animancer is to directly give it the AnimationClip you want to play so that it can create a state if needed and then reuse it each time you play that animation in the future.

Initializing states on startup adds a bit of complexity to your code and can improve performance, but only does so by putting a greater load upfront. That might be good during a loading screen, but if you instantiate a character during gameplay then you have already paid a high performance cost for doing so, meaning that it might be better not to spend even more of the current frame's time pre-initializing all the other states as well.

There are two main ways of initializing states upfront:

  • Call animancer.States.GetOrCreate (or Create) in your startup code (such as an Awake or Start method).
  • Use a NamedAnimancerComponent and assign the clips in question to its Animations array in the Inspector (or using a script). This simply calls GetOrCreate for each one in its Awake method.

If you no longer need a state, you can call AnimancerState.Destroy to remove it. Both the destroying and subsequent Garbage Collection also have a performance cost that may need to be managed.

The Performance Benchmarks section goes into further detail about the performance of Animancer.