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