07-01 Directional Basics

Location: Samples/07 Sprites/01 Directional Basics

Recommended After: Basic Movement

Learning Outcomes: in this sample you will learn:

How to organise animations in groups of up/right/down/left.

How to use Directional Animation Sets.

16x16 Mage
Created by saint11
CC0 Licence

Summary

This sample demonstrates how to implement a character that can move in 4 directions (up/right/down/left) using simple data structures and reusable code.

Overview

The general code structure is very similar to previous samples, but it uses Directional Animation Sets instead of directly referencing individual AnimationClips:

Fields

Where the other samples directly reference individual AnimationClips or use Transitions, this sample uses Directional Animation Sets which are ScriptableObject assets that contain references to multiple AnimationClips.

We also need to store the direction the character is facing when they move so that when they stop they can still play the correct Idle animation to continue facing in that direction. Having this as a Serialized Field allows us to determine which direction the character will be facing on startup as well as in Edit Mode.

DirectionalBasics Script DirectionalAnimationSet Asset
[SerializeField]
private AnimancerComponent _Animancer;

[SerializeField]
private DirectionalAnimationSet _Idles;

[SerializeField]
private DirectionalAnimationSet _Walks;

[SerializeField]
private Vector2 _Facing = Vector2.down;

If you have Inspector Gadgets Pro, you can use its Nested Object Drawers feature (by clicking on the foldout arrows) to see and modify the details of the referenced asset without needing to actually go and select that asset:

Playing

Since we know which direction we are _Facing, we can have a method that takes any DirectionalAnimationSet, gets the animation for that direction from the set, and plays it like any other animation:

private void Play(DirectionalAnimationSet animations)
{
    AnimationClip clip = animations.GetClip(_Facing);
    _Animancer.Play(clip);
}

Controls

This sample controls the character movement using the WASD Keys, which is implemented by the Sample Input script:

protected virtual void Update()
{
    Vector2 input = SampleInput.WASD;

If the player is trying to move, we store that input as the direction they want to be _Facing:

    if (input != Vector2.zero)
    {
        _Facing = input;

Then we can simply play the appropriate Walk animation for that direction:

        Play(_Walks);

This sample doesn't have any different animations for running, but we can easily allow the character to run by increasing the animation speed when the player holds Left Shift. We could have had our Play method return the AnimancerState it gets from _Animancer.Play, but we can also access it using _Animancer.States.Current:

        bool isRunning = SampleInput.LeftShiftHold;
        _Animancer.States.Current.Speed = isRunning ? 2 : 1;
    }

Note that changing the AnimancerState.Speed is a Pro-Only Feature. Animancer Lite allows you to try it out in the Unity Editor, but it will do nothing in runtime builds unless you purchase Animancer Pro.

Finally, we can simply return to one of the _Idles when the player stops trying to move. Note that we aren't setting the _Facing direction in this case, so it will still be facing in the last direction it moved:

    else
    {
        Play(_Idles);
    }
}

This sample doesn't actually move the character around since is just demonstrating the basics of Directional Animation Sets, but the Directional Character sample does demonstrate movement.

Edit Mode

If we were to make another character with some different DirectionalAnimationSets, it would use those animations at runtime but it wouldn't actually show the correct sprite in Edit Mode unless we re-assign it manually. Fortunately, Animancer allows you to easily apply and even play animations in Edit Mode. All we need to do it use MonoBehaviour.OnValidate to call AnimancerUtilities.EditModeSampleAnimation:

#if UNITY_EDITOR
private void OnValidate()
{
    // We need to null-check the _Idles to prevent GetClip from throwing an exception if it's not assigned yet.
    // But EditModeSampleAnimation will take care of null-checking the AnimationClip and _Animancer.
    if (_Idles != null)
        _Idles.GetClip(_Facing).EditModeSampleAnimation(_Animancer);
}
#endif

The #if UNITY_EDITOR isn't actually necessary because Unity won't call OnValidate at runtime anyway, but this allows us to be clearer about what the code is doing.

Conclusion

Click here to see the full DirectionalBasics script.

using Animancer;
using UnityEngine;

public class DirectionalBasics : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private DirectionalAnimationSet _Idles;
    [SerializeField] private DirectionalAnimationSet _Walks;
    [SerializeField] private Vector2 _Facing = Vector2.down;
    
    protected virtual void Update()
    {
        Vector2 input = SampleInput.WASD;
        if (input != Vector2.zero)
        {
            _Facing = input;

            Play(_Walks);

            bool isRunning = SampleInput.LeftShiftHold;
            _Animancer.States.Current.Speed = isRunning ? 2 : 1;
        }
        else
        {
            Play(_Idles);
        }
    }

    private void Play(DirectionalAnimationSet animations)
    {
        AnimationClip clip = animations.GetClip(_Facing);
        _Animancer.Play(clip);
    }

#if UNITY_EDITOR
    private void OnValidate()
    {
        if (_Idles != null)
            _Idles.GetClip(_Facing).EditModeSampleAnimation(_Animancer);
    }
#endif
}

Now we can easily create more DirectionalAnimationSets and reuse the same script for more characters.

16x16 Animated Critters
Created by patvanmackelberg
CC0 Licence

Antifarea's RPG sprite set 1
Created by Antifarea
CCBY Licence
Not included in Animancer due to Asset Store licensing restrictions.

Sub-Assets

Since the there are lots of animations in this sample and they are each only used by a single DirectionalAnimationSet, the Drag and Drop Sub-Assets feature of Inspector Gadgets Pro was used to turn the animations into sub-assets of the set in order to organise them a bit better. This has absolutely no effect on how the animations can be used, it's purely for organization during development.

What Next?

Sample Topic
Directional Character Uses Directional Animation Sets in a more complex character which moves around the scene and can include diagonal movement.