02-01 Named Character

Location: Samples/02 Fine Control/01 Named Character

Recommended After: Library Character

Learning Outcomes: in this sample you will learn:

How to use Aliases in a Transition Library.

How to use String Assets and String References.

Summary

This sample demonstrates the same behaviour as Library Character except that it uses Aliases for the script to refer to the Transition Assets by name instead of directly referencing them.

This shows how Animancer can be used, not how it should be used.

Direct references are more reliable and efficient for most use cases.

Overview

The code structure is similar to the Library Character sample, except the Transition Library references a String Asset as an Alias for each of the animations and the script refers to them using those Aliases.

NamedCharacterAnimations is almost identical to LibraryCharacterAnimations from the Library Character sample except that it uses StringAssets instead of TransitionAssets and TryPlay instead of Play:

using Animancer;
using UnityEngine;

public class NamedCharacterAnimations : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private StringAsset _Idle;
    [SerializeField] private StringAsset _Move;
    [SerializeField] private StringAsset _Action;

    private State _CurrentState;

    private enum State
    {
        NotActing,// Idle and Move can be interrupted.
        Acting,// Action can only be interrupted by itself.
    }

    protected virtual void Update()
    {
        switch (_CurrentState)
        {
            case State.NotActing:
                UpdateMovement();
                UpdateAction();
                break;

            case State.Acting:
                UpdateAction();
                break;
        }
    }

    private void UpdateMovement()
    {
        _CurrentState = State.NotActing;

        float forward = SampleInput.WASD.y;
        if (forward > 0)
        {
            _Animancer.TryPlay(_Move);
        }
        else
        {
            _Animancer.TryPlay(_Idle);
        }
    }

    private void UpdateAction()
    {
        if (SampleInput.LeftMouseUp)
        {
            _CurrentState = State.Acting;

            AnimancerState state = _Animancer.TryPlay(_Action);
            state.Events(this).OnEnd ??= UpdateMovement;
        }
    }
}

Named Animancer Component

Before properly getting into this sample, it's worth noting that using a NamedAnimancerComponent is an even simpler way to play animations by name for simple situations.

  • Every AnimancerState can be given a Key and then later referred to using that Key.
  • Transitions use themselves as the Key for the states they create.
  • When playing an AnimationClip directly, an AnimancerComponent uses the clip as the Key of its own state.
  • A NamedAnimancerComponent instead uses the name of the clip so you can play it using animancer.TryPlay("Clip Name").
  • You can manually set a state's Key to whatever you want.

Using a NamedAnimancerComponent avoids the need for a Transition Library and String Assets so it's easier to set up, but gives you a much more fragile code structure so it generally isn't recommended.

String Assets

A String Asset is just an asset that doesn't really contain anything, it just exists to have its name used for things such as Aliases.

They can be created using the Assets/Create/Animancer/String Asset menu function or via the Inspector of any StringAsset field.

Defining Aliases

In the top left of the Transition Library window has a dropdown menu which lets you go to the Transition Aliases page where each animation can be given one or more String Assets to define their Aliases.

Using Aliases

The String Assets are referenced in the script using Serialized Fields just like any other asset.

Code Inspector
[SerializeField]
private AnimancerComponent _Animancer;

[SerializeField]
private StringAsset _Idle;

[SerializeField]
private StringAsset _Move;

[SerializeField]
private StringAsset _Action;

When you Play an AnimationClip or Transition, you're giving Animancer everything it needs to create an AnimancerState if there wasn't already one for that Key:

// LibraryCharacterAnimations.cs.
_Animancer.Play(_Move);

But since this script only has the Aliases, it needs to use TryPlay to acknowledge that it's depending on something defined somewhere else:

// NamedCharacterAnimations.cs.
_Animancer.TryPlay(_Move);

Alias All

You might have noticed the Alias All Transitions toggle at the top of the Transition Aliases page.

If you don't want to give the library a String Asset for each animation, you can enable that toggle to have it automatically register them all using the name of their Transition Assets as their Alias.

String References

If you don't want to give the script a String Asset for each animation, you can use String References instead.

public static class HumanoidAnimations
{
    public static readonly StringReference Idle = "Idle";
    public static readonly StringReference Move = "Move";
    public static readonly StringReference Action = "Action";
}

Having that static class would allow any of your scripts to call _Animancer.TryPlay(HumanoidAnimations.Move);. That means you don't need to give them references to the String Assets in the Inspector, but it makes the script much less flexible since it will only work with that specific name.

Conclusion

Using Aliases for something this simple is obviously silly, but there are some cases where it can be useful.

What Next?

Sample Topic
Characters Implementing the same behaviour as this sample using Animancer's Finite State Machine system to better prepare for more complex situations.
Animation Serialization Serializing the current animation details of a character to save in a file or send over a network.