01-03 Basic Action

Location: Samples/01 Basics/03 Basic Action

Recommended After: Basic Movement

Learning Outcomes: in this sample you will learn:

How to wait for an animation to finish then play something else.

How to use End Events.

How to set an animation's time.

Summary

This sample demonstrates how to make a character perform an Action then return to Idle after it finishes.

  • Animancer's Play methods return an AnimancerState which you can use to control the animation.
AnimancerState state = _Animancer.Play(_Action);
  • You can restart an animation by setting its Time to 0.
state.Time = 0;
  • End Events let you register a method to run when an animation ends.
state.Events(this).OnEnd ??= OnEnable;
  • The Transitions sample re-implements the same behaviour with smooth blending between the animations (i.e. Cross Fading).

Overview

The code structure is the same as to the Basic Movement sample, just with a different script and action animation instead of movement.

Action Animation

The fields and OnEnable method are basically the same as in previous samples so we won't go over them again.

This time we want to know when the player clicks the mouse, so we make an Update method to play the _Action animation when that happens:

protected virtual void Update()
{
    if (SampleInput.LeftMouseUp)// Was the left mouse button released this frame?
    {
        _Animancer.Play(_Action);
    }
}

So far, the full script looks like this:

using Animancer;
using UnityEngine;

public class PlayAnimationOnClick : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private AnimationClip _Idle;
    [SerializeField] private AnimationClip _Action;
    
    protected virtual void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    protected virtual void Update()
    {
        if (SampleInput.LeftMouseUp)
        {
            _Animancer.Play(_Action);
        }
    }
}

If you save that script and return to Unity, you can attach it to your character and set up its references in the Inspector:

Then if you enter Play Mode, you can Left Click to play the Action animation:

Remember to exit Play Mode once you're done looking.

End Event

As you can see above, the animation plays correctly but afterwards the character freezes in place which is usually not what you want to happen. In this case when the _Action animation ends we want the character to go back to the _Idle animation, which is really easy to do in Animancer.

First, we grab the AnimancerState returned by the Play method:

AnimancerState state = _Animancer.Play(_Action);

That state allows you to get and set all the playback details of the animation such as its Speed, Time, and in this case its End Event:

state.Events(this).OnEnd ??= OnEnable;

Using ??= means it will only assign the callback if it was previously null, which is good for performance because it avoids allocating the same callback every time. The End Events page explains it in more detail.

You would usually make a new method for the event to call, but in this sample the OnEnable method already does exactly what we want so we can just use it.

The full script now looks like this:

using Animancer;
using UnityEngine;

public class PlayAnimationOnClick : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private AnimationClip _Idle;
    [SerializeField] private AnimationClip _Action;

    protected virtual void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    protected virtual void Update()
    {
        if (SampleInput.LeftMouseUp)
        {
            AnimancerState state = _Animancer.Play(_Action);
            state.Events(this).OnEnd ??= OnEnable;
        }
    }
}

If you save that script and take another look at it in Play Mode, now the character will return to Idle after performing the Action.

Remember to exit Play Mode once you're done looking.

Rapid Fire

So far the character has had to wait for the Action animation to finish before they can act again because Animancer doesn't automatically restart the animation when you call Play. This behaviour was useful in the Basic Movement sample, but there are many cases where you might want to force the animation back to the beginning which can be done by simply setting its Time to 0.

AnimancerState state = _Animancer.Play(_Action);
state.Time = 0;
state.Events(this).OnEnd ??= OnEnable;

The full script now looks like this:

using Animancer;
using UnityEngine;

public class PlayAnimationOnClick : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private AnimationClip _Idle;
    [SerializeField] private AnimationClip _Action;

    protected virtual void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    protected virtual void Update()
    {
        if (SampleInput.LeftMouseUp)
        {
            AnimancerState state = _Animancer.Play(_Action);
            state.Time = 0;
            state.Events(this).OnEnd ??= OnEnable;
        }
    }
}

What Next?

Sample Topic
Transitions Implementing the same behaviour as this sample with smooth blending instead of instantly snappping between animations.
Basic Character Combining this sample and Transitions with Basic Movement.