How to check if a certain animation state from an animator is running?

TheMatrixAgent22 picture TheMatrixAgent22 · May 21, 2018 · Viewed 12.1k times · Source

I created an animator called "m4a4animator". Inside it, the main function is called "idle" (nothing), and other 2 states: "shoot" (mouse0) and "reload" (R). These 2 animation states are transitioned to "idle". Now, everything is working... but the only problem I have is this: if I am in the middle of reloading and and press mouse0 (shoot), the animation running state immediately changes to shoot... but I want to block that.

Now, the question: How can I stop CERTAIN animation changes while an animation is running?

Here is my animator

And here is my script:

using UnityEngine;
using System.Collections;

public class m4a4 : MonoBehaviour {

    public Animator m4a4animator;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown (KeyCode.R)) {

            m4a4animator.Play("reload");

        }

        if (Input.GetMouseButton(0)) {

            m4a4animator.Play("shoot");

        }
    }
}

Answer

Programmer picture Programmer · May 21, 2018

For the legacy Animation system, Animation.IsPlaying("TheAnimatonClipName) is used to check if the animation clip is playing.


For the new Mechanim Animator system, you have to check if both anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) and anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f) are true. If they are then animation name is currently playing.

This can be simplified like the function like the Animation.IsPlaying function above.

bool isPlaying(Animator anim, string stateName)
{
    if (anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
            anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
        return true;
    else
        return false;
}

Now, everything is working... but the only problem I have is this: if I am in the middle of reloading and and press mouse0 (shoot), the animation running state immediately changes to shoot... but I want to block that.

When the shoot button is pressed, check if the "reload" animation is playing. If it is, don't shoot.

public Animator m4a4animator;
int animLayer = 0;

// Update is called once per frame
void Update()
{
    if (Input.GetKeyDown(KeyCode.R))
    {
        m4a4animator.Play("reload");
    }

    //Make sure we're not reloading before playing "shoot" animation
    if (Input.GetMouseButton(0) && !isPlaying(m4a4animator, "reload"))
    {
        m4a4animator.Play("shoot");
    }
}

bool isPlaying(Animator anim, string stateName)
{
    if (anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
            anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
        return true;
    else
        return false;
}

If you need to wait for the "reload" animation to finish playing before playing the "shoot" animation then use a coroutine. This post described how to do so.