Animancer v6.0 is currently available for testing.

01 Quick Play

Difficulty: Beginner

Location: Assets/Plugins/Animancer/Examples/01 Basics/01 Quick Play

Namespace: Animancer.Examples.Basics

This example demonstrates how to use Animancer to implement some simple behaviour:

  1. Start with an idle animation.
  2. When the user clicks the mouse, perform an action.
  3. When that action is complete, return to idle.

If you just want to play a single animation without any scripting, check out the Solo Animation example.

It consists of one very simple script called PlayAnimationOnClick:

  • It references an AnimancerComponent instead of referencing the Animator like you would without Animancer. Most interactions with Animancer are done via that component.
  • It also references two AnimationClips which contain the actual animation data that defines how the model will move over time.
  • These references are all Serialized Fields, meaning they can be assigned using the Inspector.
  • The scene contains two copies of the same model with the same scripts attached, but different animations assigned to show how this simple script can be reused for different purposes.
  • The Golf Events example is an extension of this one which shows how to trigger a function at a specific time during an animation to hit a ball and also how to adjust the transition back to idle to look more natural.

Tutorial

This tutorial takes you through a step by step process of implementing a PlayAnimationOnClick script and setting up a scene to see it in action. Since this is the first example, it covers the basics more thoroughly than the rest. Click here to see the full script.

using Animancer;
using UnityEngine;

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

    private void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            var state = _Animancer.Play(_Action);
            state.Events.OnEnd = OnActionEnd;
        }
    }

    private void OnActionEnd()
    {
        _Animancer.Play(_Idle);
    }
}

And this is what the Inspector looks like:

Start by following the Basic Scene Setup instructions to create a new scene with the character in it.

New Script

Create a New Script by right clicking in the Project window and selecting Create/C# Script. Call it PlayAnimationOnClickTutorial and open it up in your IDE (such as Visual Studio). The script included in the example is called PlayAnimationOnClick so we just put Tutorial on the end to avoid conflicts while you make the same script from scratch. Edit the script so that it looks like this:

using Animancer;
using UnityEngine;

public sealed class PlayAnimationOnClickTutorial : MonoBehaviour
{
}
  • The Namespaces section explains the reason for those using statements.
  • public is an Access Modifier which allows any other scripts to access this class if they want to (unlike the other modifiers).
  • The Inheritance page explains the reason for the : MonoBehaviour.
  • The script does not currently contain either of the Start or Update methods which Unity puts in new scripts by default, so instead of needing to manually remove them from every new script you might consider replacing your Default Script Template.
  • That page also explains why the class is marked as sealed.
  • Note that because this is a MonoBehaviour script, Unity requires that the class name (PlayAnimationOnClickTutorial) must exactly match the file name (PlayAnimationOnClickTutorial.cs).

Idle Animation

Now let's get the idle animation working.

The first thing the script needs is a reference to an AnimancerComponent which we could get using one of two main ways:

  • The GetComponent method would get a component of the appropriate type attached to the same GameObject.
  • A Serialized Field would cause it to show a field in the Inspector so that we can assign an object of the appropriate type from anywhere in the scene.

The Composition section explains the differences between them in a bit more detail, including the reason why the Animancer examples favour Serialized Fields.

So we declare a Serialized Field inside the class like so:

[SerializeField] private AnimancerComponent _Animancer;

Or you can use multiple lines if you prefer:

[SerializeField]
private AnimancerComponent _Animancer;

Since AnimancerComponent is in the Animancer Namespace, we either need to put using Animancer; at the top of the script or we need to specify the full name of the type as Animancer.AnimancerComponent.

We also need a reference to the idle animation, so let's add another field:

[SerializeField] private AnimationClip _Idle;

Then we can just tell it to play that animation on startup using an OnEnable method, which is one of the MonoBehaviour Messages (meaning that it has that specific name so Unity will call it for us on startup):

private void OnEnable()
{
    _Animancer.Play(_Idle);
}

See the Methods page if you are unfamiliar with the concept of methods.

The full script now looks like this:

using Animancer;
using UnityEngine;

public sealed class PlayAnimationOnClickTutorial : MonoBehaviour
{
    [SerializeField] private AnimancerComponent _Animancer;
    [SerializeField] private AnimationClip _Idle;
    
    private void OnEnable()
    {
        _Animancer.Play(_Idle);
    }
}

Let's save the script and go back to Unity to see it in action.

  1. Select your character in the Hierarchy window (the root object with the Animator component).
  2. Make sure the Apply Root Motion toggle is deselected since we do not want any movement in this example.
  3. Add an AnimancerComponent if you didn't do so already as part of the Basic Scene Setup.
  4. Add the PlayAnimationOnClickTutorial script you just created.
  5. Drag and drop the AnimancerComponent into the Animancer field in that component.
  6. Use the circular icon next to the Idle field to open the Object Picker window to find the Idle animation you want to use. The original example uses Humanoid-GolfSwingReady.

Click here if you are wondering why some things look a little different from Unity's defaults in that video.

It's because of a plugin called Inspector Gadgets (also made by Kybernetik like Animancer).

It replaces the default Transform Inspector to add features like the [C][P][S] buttons on the right to Copy and Paste values between objects, and Snap them to the grid or the [=] button on the left which toggles the Scale field from a single value to the regular x/y/z vector field.

Inspector Gadgets Pro also adds [H][S][A] buttons to the object reference fields (on the right of the PlayAnimationOnClickTutorial script) while they are null to allow you to find a reference in a single click by searching the Hierarchy (parents and children of the current object), the current Scene, or all Assets in the project. So we could have just clicked the [H] to get the AnimancerController reference from the same object instead of dragging and dropping it. Note how the Idle field didn't have a [H] button because AnimationClips are assets, not scene objects.

Now if you press Play (the triangular button in the top center of the Unity Editor), the model will be playing the idle animation you gave it:

Remember to exit Play Mode after you are done looking.

Golf Club

That pose looks a bit funny without anything to hold so let's give him a golf club.

  1. Expand the character's hierarchy until you reach the RightHandHolder bone (an extra bone which is a child of the right hand in a good position for holding objects). Note that if you hold Alt when you expand or collapse something, it will do the same for all of that object's children as well.
  2. Go to the Assets/Plugins/Animancer/Examples/Art/Props folder.
  3. Drag the GolfClub prefab from the Project window onto the RightHandHolder object in the Hierarchy window (a child of the right hand bone) to instantiate the prefab as a child of that bone. The position and rotation of the GolfClub should all be at 0.

Note that a "bone" is simply a regular GameObject / Transform which deforms the character model as it moves and rotates. So even though the RightHandHolder is part of the FBX file the model comes from, it is not really a bone because it does not affect the model (it is simply there to make it easy to position objects in the hand).

Now he will be holding the golf club when we press Play.

Remember to exit Play Mode after you are done looking.

Swing Animation

A golf club won't do much good if he can't swing it, so let's get on that.

First we need to add another AnimationClip field to the script. Just make a copy of the _Idle field and rename it to _Action.

Then we want to know when the player clicks the mouse, so let's make an Update method to check that:

private void Update()
{
    // GetMouseButtonDown returns true for one frame when you first click the mouse.
    // The parameter specifies which mouse button we want:
    // 0 = Left Click.
    // 1 = Right Click.
    // 2 = Middle Click.
    if (Input.GetMouseButtonDown(0))
    {
    }
}

See the Methods page for more information about Flow Control (the if statement), Parameters, and Return Values.

Inside that if block we want to play the _Action animation, so we can just copy the contents of the OnEnable method and change the parameter.

The full script now looks like this:

using Animancer;
using UnityEngine;

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

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            _Animancer.Play(_Action);
        }
    }
}

Save the script again and go back to Unity.

Before it will do anything, we need to give it the swing animation. Just select the character and assign the Action animation in the Inspector the same way we assigned the Idle. The original example uses the Humanoid-GolfSwing animation.

Now when we enter Play Mode we can click to trigger the swing animation.

Remember to exit Play Mode after you are done looking.

After the Action

The character now has an obvious problem: he can swing like a champ, but then he gets delayed stagefright and freezes in place. Fortunately there's a simple cure for that if we go back to the script.

All we need to do is wait until the animation is done then return to idle so let's first create a method to be called:

private void OnActionEnd()
{
    _Animancer.Play(_Idle);
}

Then we can go back to the Update method, grab the AnimancerState returned by Play, and assign that new method as a callback to its OnEnd event:

var state = _Animancer.Play(_Action);
state.Events.OnEnd = OnActionEnd;

There are a couple of different ways we could have done that which are listed on the AnimancerEvent.Sequence.OnEnd page. The End Events page also explains some alternative approaches instead of using the OnEnd callback.

The full script looks like this:

using Animancer;
using UnityEngine;

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

    private void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            var state = _Animancer.Play(_Action);
            state.Events.OnEnd = OnActionEnd;
        }
    }

    private void OnActionEnd()
    {
        _Animancer.Play(_Idle);
    }
}

If we take another look at it in Play Mode we can see the character return to idle after the swing so we can click to swing again.

Remember to exit Play Mode after you are done looking.

Smooth Transitions

There's still an obvious problem with it though: when the swing ends, the character snaps instantly back to idle instead of moving smoothly from where the swing ended. This could be solved by making sure that the swing animation ends in exactly the same pose where the idle starts, but that is not always practical. Fortunately, this can be easily solved by Cross Fading between the animations. The Playing and Fading example goes into more detail on the subject, but let's give it a quick try here.

All you need to do is add another parameter to the Play call to tell it how long you want the transition to take:

_Animancer.Play(_Idle);// Play instantly.
_Animancer.Play(_Idle, 0.25f);// Cross Fade over 0.25 seconds.

The final script looks like this:

using Animancer;
using UnityEngine;

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

    private void OnEnable()
    {
        _Animancer.Play(_Idle);
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            var state = _Animancer.Play(_Action);
            state.Events.OnEnd = OnActionEnd;
        }
    }

    private void OnActionEnd()
    {
        _Animancer.Play(_Idle, 0.25f);
    }
}

And here is what it looks like in Play Mode:

Note that Animancer Lite only allows a fade duration of 0.25 seconds. You can try out any duration you want in the Unity Editor, but it will warn you that it will always use the default duration in runtime builds unless you purchase Animancer Pro.

What Next?

That is all for this first tutorial, but there are plenty more where that came from:

  • If you want to easily customise animation details such as the fade duration in the Inspector instead of hard-coding them in your scripts, you can use Transitions.
  • The Playing and Fading example goes into more detail about the differences between the various parameter combinations you can give when calling the Play method.
  • The Golf Events example builds upon this example to show how you can use Animation Events to trigger a function at a specific time during an animation to hit a ball and also how to adjust the transition back to idle to look more natural.

The up arrow in the bottom right corner of the page will take you back to the top.