(Contains code snippet from other answer. Credit to their respective author)
Simpler version
Involve GC alloc on Animator.parameters, not cool for repeated call.
public static bool HasParameter( string paramName, Animator animator )
{
foreach( AnimatorControllerParameter param in animator.parameters )
{
if( param.name == paramName )
return true;
}
return false;
}
// Usage sample
public void SetFloatParamWithCheck( string paramName, float v )
{
// animator defined elsewhere.
Animator animator;
if( HasParameter( animator, paramName ) )
{
animator.SetFloat( paramName , v );
}
}
Extension version
still involve GC alloc every call.
public static class AnimatorHelper
{
public static bool ContainsParam( this Animator _Anim, string _ParamName )
{
foreach( AnimatorControllerParameter param in _Anim.parameters )
{
if( param.name == _ParamName ) return true;
}
return false;
}
}
// Usage sample
public void SetFloatParamWithCheck( string paramName, float v )
{
// animator defined elsewhere.
Animator animator;
if( animator.ContainsParam( paramName ) )
{
animator.SetFloat( paramName , v );
}
}
An over-engineered version
With caching and resolving parameter hash in one go. Premature optimization is evil but you will need it in (some) practice.
// Animator parameters query involve GC, cache it
// Animator.GetParameter( index ) might also internally use it, so no better.
// Assume typically working with 1 animator, could extending to collect more cache.
Animator m_LastAnimatorCache;
// <key=paramname,value=hash>
Dictionary<string,int> m_AnimatorParamCache = new Dictionary<string,int>( );
private bool TryGetAnimatorParam( Animator animator, string paramName, out int hash )
{
// Rebuild cache
if( (m_LastAnimatorCache == null || m_LastAnimatorCache != animator) && animator != null )
{
m_LastAnimatorCache = animator;
m_AnimatorParamCache.Clear( );
foreach( AnimatorControllerParameter param in animator.parameters )
{
int paramHash = Animator.StringToHash( param.name ); // could use param.nameHash property but this is clearer
m_AnimatorParamCache.Add( param.name, paramHash );
}
}
if( m_AnimatorParamCache != null && m_AnimatorParamCache.TryGetValue( paramName, out hash ) )
{
return true;
}
else
{
hash = 0;
return false;
}
}
// Usage sample
public void SetFloatParamWithCheck( string paramName, float v )
{
// animator defined elsewhere.
Animator animator;
int hash;
if( TryGetAnimatorParam( animator, paramName, out hash ) )
{
animator.SetFloat( hash, v );
}
}
it works! but produces garbage if many parameters are present in the animator controller
– pavan3k