Animator Parameter Name Field

Sometimes we want to refer to an Animator Parameter from the inspector by name. In this case, there is a chance we don’t remember the names of the animator parameters. This doesn’t look like a big deal, but it’s proven that only a few clicks can increase the work time by a lot if these few clicks are frequent.

The following code improves the single text field with a drop-down button. This will show you all the parameters of the Animator on this object. You can also filter the list by animator parameter type.
Let’s get started!

Animator Parameter Attribute

First, we need to create a new Attribute. We need two variables for this class. A Type value that will be an AnimatorControllerParameterType and the other variable will be the FilterByType boolean. This will tell us whether or not we want to filter our parameter names based on their types.

public class AnimatorParameterAttribute : PropertyAttribute
{
   // Determines whether or not we are using Type to filter the list.
   public bool FilterByType;

   // We will only show parameters of this type.
   public AnimatorControllerParameterType Type;

   public AnimatorParameterAttribute() { }
   public AnimatorParameterAttribute(AnimatorControllerParameterType type)
   {
      FilterByType = true;
      Type = type;
   }
}

Animator Parameter Drawer

The next step is to create our Property Drawer class. This will be more complex, but the basic idea is this: 

We will grab the property (or variable if you wish) that is marked with the previously created Animator Parameter Attribute. This will give us a SerializedProperty type of variable.

From this SerializedProperty object we can reach our actual script (.targetObject) and from there the GameObject it’s attached to, finally, the Animator that is on this GameObject.

If we have the Animator as a reference, we can go through its parameters and collect all the names we want (filtered or not by types).

Lastly, we draw a PropertyField for our string variable (this will be a simple TextField) and a little button for the dropdown list.

[CustomPropertyDrawer(typeof(AnimatorParameterAttribute))]
public class AnimatorParameterDrawer : PropertyDrawer
{
   GUIStyle _popupStyle;

   int _index;
   List<string> _names = new List<string>();
 
   public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
   {
      // Reset Names
      _names.Clear();
      _index = -1;

      // Get the Attribute
      AnimatorParameterAttribute attr = attribute as AnimatorParameterAttribute;

      // Grab the animator from the property
      var go = (property.serializedObject.targetObject as MonoBehaviour).gameObject;
      Animator a = go.GetComponent<Animator>();
      if (a != null)
      { 
         a.Rebind();

         // Iterate through the parameters
         int cnt = -1;
         foreach (var p in a.parameters)
         {
            // If the attribute is not filtered, or it has the same type
            if (!attr.FilterByType || attr.Type == p.type)
            {
               _names.Add(p.name);
               cnt++;
               if (p.name == property.stringValue)
                  _index = cnt;
            }
         } 
      }
 
      // Init popupstyle
      if (_popupStyle == null)
      {
         _popupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions"));
         _popupStyle.imagePosition = ImagePosition.ImageOnly;
      }
      
      // Draw the property
      label = EditorGUI.BeginProperty(position, label, property);
      position = EditorGUI.PrefixLabel(position, label);

      EditorGUI.BeginChangeCheck();
      int indent = EditorGUI.indentLevel;
      EditorGUI.indentLevel = 0;

      if (_names.Count == 0)
      {
         GUI.Label(position, "No Animator is attached or it has no parameters");
      }
      else
      { 
         // Calculate rect for configuration button
         Rect buttonRect = new Rect(position);
         buttonRect.yMin += _popupStyle.margin.top;
         buttonRect.width = _popupStyle.fixedWidth + _popupStyle.margin.right;
         position.xMin = buttonRect.xMax;

         // Show a simple text field
         EditorGUI.PropertyField(position, property, GUIContent.none);
 
         // Draw a dropdown button for selecting the parameter name.
         int result = EditorGUI.Popup(buttonRect, _index, _names.ToArray(), _popupStyle);
         if (_index != result && result >= 0 && result < _names.Count)
         {
            Debug.Log(_index);
            _index = result;
            property.stringValue = _names[_index];
         } 
      }

      if (EditorGUI.EndChangeCheck())
         property.serializedObject.ApplyModifiedProperties();

      EditorGUI.indentLevel = indent;
      EditorGUI.EndProperty(); 
   }
}

Using this Attribute

Once you created these two classes, you can start to use your new Attribute. Important to note the Attribute only works with string variables. 

This is how you use it:

[AnimatorParameter] 
public string ParameterName;

This is a basic usage, the dropdown will contain every parameter name you have in the Animator that is on this GameObject. However, you can define a type to show only those parameters that have the given type. 

You can do it this way:

[AnimatorParameter(AnimatorControllerParameterType.Float)] 
public string ParameterName;

You can use the following types:

  • AnimatorControllerParameterType.Float
  • AnimatorControllerParameterType.Int
  • AnimatorControllerParameterType.Bool
  • AnimatorControllerParameterType.Trigger

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.