- Home /
is there a way to check if an animatorcontroller has a parameter?
With mecanim, if you try to set a parameter that doesn't exist, it logs a warning. It doesn't throw an exception or return null or anything useful like that. So if I set a parameter very often that doesn't exist, a lot of CPU time is spent logging warnings. How can I tell if a parameter exists in an animatorcontroller? It would be great if there was a method like ProceduralMaterial.HasProceduralProperty (which allows you to check if the ProceduralMaterial has the property in question).
(crossposted from gamedev.stackexchange)
Answer by drod7425 · Nov 08, 2013 at 03:53 PM
Unfortunately, there doesn't seem to be anything in place to check if a parameter exists. If you just want to turn off warnings to save CPU, set Animator.logWarnings = false (not in the scripting reference for some reason). If you want something that will do error handling, I wrote a hacky way to do it:
void Awake(){
animator.SetBool("nonExistant",true);
if(!animator.GetBool("nonExistant")){
Debug.LogError("The parameter nonExistant does not exist! Fix it!");
}else{
animator.SetBool("nonExistant",false);
}
}
Hope this helps!
Answer by thexdd · Aug 17, 2015 at 03:10 PM
I know its quite an old topic, but maybe somebody is still looking for any other options of how to deal with it. Here is my solution:
public static bool HasParameter(string paramName, Animator animator)
{
foreach (AnimatorControllerParameter param in animator.parameters)
{
if (param.name == paramName)
return true;
}
return false;
}
it works! but produces garbage if many parameters are present in the animator controller
Ins$$anonymous$$d of using parameters you should use
parameterCount and
GetParameter in a normal "for" loop.
edit
Well I though this might help with garbage but it actually makes things worse ^^. I though that GetParameter is a direct accessing method for a single parameter. However under the hood GetParameter actually uses the parameters property so this is completely pointless.
Though as i said in my old comment the information if the animator has a certain parameter or not does not change over time. So getting this information at start and caching it would be the best approach.
Answer by RChrispy · Sep 29, 2015 at 10:21 AM
I found the code of @inferno222 and @thexdd realy useful. So I made an extension real quick should work. But such calls should not be done in an Update! Store the outcome during a Start() in a variable and use this variable!!!
Just add it into your projekt I use a lot of extensions.
public static bool ContainsParam(this Animator _Anim, string _ParamName)
{
foreach (AnimatorControllerParameter param in _Anim.parameters)
{
if (param.name == _ParamName) return true;
}
return false;
}
Use like this:
void start() {
tOutcome = myAnimator.ContainsParam("JumpCount");
}
And then you can ask for:
if( tOutcome ) {
myAnimator.SetInteger("JumpCount", JumpCount);
}
How do you use that extension?
When I enter
public static bool ContainsParam(this Animator _Anim, string _ParamName)
{
foreach (AnimatorControllerParameter param in _Anim.parameters)
{
if (param.name == _ParamName) return true;
}
return false;
}
I get this error:
Extension method must be defined in a non-generic static class. Do you have a separate script that defines a public static bool ContainsParam?
You just have to define the extension in a seperate file. It is C# thing to extend existing classes horizontically.
Here is a tutorial: https://unity3d.com/de/learn/tutorials/topics/scripting/extension-methods
Answer by inferno222 · Aug 20, 2015 at 12:54 AM
A slightly shorter answer is:
public static bool HasParameter(string paramName, Animator animator)
{
foreach (AnimatorControllerParameter param in animator.parameters)
{
if (param.name == paramName) return true;
}
return false;
}
thanks, you're right, I've updated my answer. Sometimes I just should really fall asleep rather than code anything :D
Answer by mkgame · Jan 12, 2019 at 09:22 PM
I would recommend to speed up this check with a Dictionary:
Dictionary<string, bool> animNames = new Dictionary<string, bool>();
void Awake() {
animNames.Add("Attack", false);
animNames.Add("Run", false);
animNames.Add("Walk", false);
foreach (AnimatorControllerParameter param in MyAnimator.parameters) {
if (animNames.containsKey(param.Name)) {
animNames[param.Name] = true;
}
}
// To check then the known param.
if (animNames["Attack"] == true) {
// Attack param available, use it.
}
}