Check Animation State exists before playing it

Suppose I have an Animator anim. I call:

anim.Play("attack")

which works fine, if the “attack” animation exists.

But for cases when the animation state does not exist, I get an error at runtime.

Animator.GotoState: State could not be found

Question: How can I check that “attack” exists before playing it?

I thought I’d use Animator.HasState() but I don’t know what to pass it.

EDIT:
I did a little more digging, and Animator.HasState() is actually pretty easy to use.

http://unity3d.com/learn/tutorials/projects/stealth/hashids

EDIT2:
The rest of this really only works if you are using the legacy animation system, sorry…

If that doesn’t work for some reason, you could also enumerate all of the animation states and check for the one you are looking for by modifying the code sample from the manual.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Animation anim;
    void Start() {
        anim = GetComponent<Animation>();
        foreach (AnimationState state in anim) {
            if(state.name == "attack") {
                //Do your stuff here
            }
        }
    }
}

I’m not sure how much of a performance hit this generates, but if it is something you are doing a lot it might be better to establish some logic in your script that helps it determine if it can attack or not without needing to enumerate anything.

If you’re worried about a performance hit, the one thing I’d recommend is using a for loop rather than foreach. There’s a performance hit any time you use foreach, because it has to create an iterator, which runs in linear time, whereas a for loop doesn’t need to create anything. So really, it’s only an issue of how many objects you’re searching. Three to five: that happens in a Planck era on any modern processor - use whatever the heck you want. Three to five thousand (or arbitrary): you might want to optimize a bit.

For animator you can use:

var stateId = Animator.StringToHash("Movement");
var hasState = anim.HasState(0,stateId);

You can use this code. Just change “Movement” to what ever state you are looking for and “0” to your animator layer index :slight_smile:
Cheers