When AnimancerComponent.Play creates a state, it registers it in an internal Dictionary using a particular key so that it can later be retrieved using that key and reused.
- By default, the
AnimationClipthe state is playing will be used as its key, but the system allows you to use anyobjectas a key (every variable in C# is anobject). - The
NamedAnimancerComponentoverrides itsGetKeymethod to use the clip'snameinstead of theAnimationClipitself. So callinganimancer.Play(clip)uses thenameto lookup the state, but you can also pre-register the clip on startup by adding it to theAnimationsarray in the Inspector or callinganimancer.States.GetOrCreate(clip)so that later on you can callanimancer.Play("Animation Name")in any script without a direct reference to theAnimationClip. The Named Animations example explains howstringnames and other keys (such as enums) can be used in more detail.
void KeysExample(AnimancerComponent animancer, AnimationClip clip)
{
// Trying to play an animation before registering it does nothing (and returns null).
animancer.TryPlay("Attack");
// But if you create a state with a key first, then you only need that key to play it later on.
animancer.States.Create("Attack", clip);
animancer.TryPlay("Attack");
// Or you can create the state and set its key manually:
var state = new ClipState(clip);
state.Key = "Attack";
animancer.TryPlay("Attack");// This won't work because the state isn't connected to anything yet.
animancer.Layers[0].AddChild(state);// Now the state is connected and registered with its Key.
animancer.TryPlay("Attack");
}
- You don't need to set the
AnimancerState.Keyif you don't want to. You can simply create anew ClipState(or whatever type of state you want) and keep a reference to it for when you want to use it. - If you want to have multiple states playing the same clip (such as if you need to play it on multiple Layers) you will need to register them all with different keys (or not register them at all).
FadeMode.FromStartuses this to fade a clip out while fading another copy of it in at the same time.
Enum Keys
Unfortunately, since object is a Reference Type, using a Value Type like an enum in those methods implicitly creates a new object to hold the value. This is called Boxing and has a notable impact on performance, particularly since the new object is immediately discarded after the call and needs to be Garbage Collected. This does not mean enums should not be used, just that you should be aware of the inefficiency.
Object Keys
Another approach is to use actual objects as keys. Rather than an enum you could make a class like this:
public static class CharacterAction
{
public static readonly object Idle = new object();
public static readonly object Walk = new object();
public static readonly object Run = new object();
// Etc.
}
Those objects will not actually do anything on their own but can be used as keys in a similar fashion to an enum: animancer.States.Create(CharacterAction.Walk, _Walk);.
Component Keys
If a script only has one animation that it will play, it could use itself as the key, so a Walk script could create a state with animancer.States.Create(this, _Walk); and play it with animancer.Play(this). That will not work if it is actually a Movement script that handles both Walk and Run animations as separate states though.