123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- #if UNITY_EDITOR
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEditor.Animations;
- using UnityEngine;
- using static Animancer.Editor.AnimancerGUI;
- namespace Animancer.Editor
- {
- /// <summary><see cref="PropertyDrawer"/> for <see cref="ControllerState.SerializableParameterBindings"/>.</summary>
- /// https://kybernetik.com.au/animancer/api/Animancer.Editor/SerializableParameterBindingsDrawer
- [CustomPropertyDrawer(typeof(ControllerState.SerializableParameterBindings), true)]
- public class SerializableParameterBindingsDrawer : PropertyDrawer
- {
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- if (!property.isExpanded)
- return LineHeight;
- GetFields(property, out var mode, out var bindings);
- var count = bindings.arraySize;
- if (count > 0 && mode.boolValue)
- count = 1 + Mathf.CeilToInt(count * 0.5f);
- return CalculateHeight(count + 3);
- }
- /************************************************************************************************************************/
- /// <inheritdoc/>
- public override void OnGUI(Rect area, SerializedProperty property, GUIContent label)
- {
- area.height = LineHeight;
- var isExpanded = EditorGUI.PropertyField(area, property, label, false);
- if (!isExpanded)
- return;
- EditorGUI.indentLevel++;
- NextVerticalArea(ref area);
- GetFields(property, out var mode, out var bindings);
- var parameterList = GetContextParameterList(property);
- var bindingCount = bindings.arraySize;
- DoModeGUI(ref area, mode, bindingCount, parameterList);
- var modeValue = mode.boolValue;
- DoBindingCountGUI(ref area, bindings, modeValue, ref bindingCount, parameterList);
- DoBindingsGUI(area, bindings, modeValue, bindingCount, parameterList);
- EditorGUI.indentLevel--;
- }
- /************************************************************************************************************************/
- private void DoModeGUI(
- ref Rect area,
- SerializedProperty mode,
- int bindingCount,
- string parameterList)
- {
- using var label = PooledGUIContent.Acquire();
- if (bindingCount == 0)
- {
- label.text = "Bind All Parameters";
- label.tooltip =
- "If enabled, all parameters in the Animator Controller will be bound" +
- " to Animancer parameters with the same name and the Bindings array can be left empty." +
- parameterList;
- }
- else
- {
- label.text = "Rebind Names";
- label.tooltip =
- "If enabled, the Bindings array will be taken in pairs so that each" +
- " Animator Controller parameter can be bound to an Animancer Parameter with different name." +
- parameterList;
- }
- EditorGUI.PropertyField(area, mode, label, false);
- NextVerticalArea(ref area);
- }
- /************************************************************************************************************************/
- private void DoBindingCountGUI(
- ref Rect area,
- SerializedProperty bindings,
- bool mode,
- ref int bindingCount,
- string parameterList)
- {
- using var label = PooledGUIContent.Acquire(
- "Bindings",
- "The names of parameters in the Animator Controller to bind to Animancer parameters." +
- "\n� Leave this array empty and enable the toggle if you want to bind all parameters." +
- parameterList);
- var newCount = bindingCount;
- if (mode && bindingCount > 0)
- newCount /= 2;
- newCount = EditorGUI.DelayedIntField(area, label, newCount);
- if (newCount < 0)
- newCount = 0;
- else if (mode && newCount > 0)
- newCount *= 2;
- if (bindingCount != newCount)
- {
- bindingCount = newCount;
- bindings.arraySize = newCount;
- }
- NextVerticalArea(ref area);
- }
- /************************************************************************************************************************/
- private void DoBindingsGUI(
- Rect area,
- SerializedProperty bindings,
- bool mode,
- int bindingCount,
- string parameterList)
- {
- if (bindingCount <= 0)
- return;
- using var label = PooledGUIContent.Acquire();
- if (mode)
- {
- var controllerArea = EditorGUI.IndentedRect(area);
- controllerArea.xMin -= 1;// Not sure why.
- var animancerArea = StealFromRight(ref controllerArea, controllerArea.width * 0.5f, StandardSpacing);
- label.text = "Controller";
- label.tooltip = "The name of the Animator Controller parameter" + parameterList;
- GUI.Label(controllerArea, label);
- label.text = "Animancer";
- label.tooltip = "The name of the Animancer parameter";
- GUI.Label(animancerArea, label);
- NextVerticalArea(ref controllerArea);
- NextVerticalArea(ref animancerArea);
- for (int i = 0; i < bindingCount; i++)
- {
- DoBindingGUI(ref controllerArea, bindings, i, GUIContent.none);
- i++;
- DoBindingGUI(ref animancerArea, bindings, i, GUIContent.none);
- }
- }
- else
- {
- EditorGUI.indentLevel++;
- label.tooltip = "";
- for (int i = 0; i < bindingCount; i++)
- {
- label.text = "Binding " + i;
- DoBindingGUI(ref area, bindings, i, label);
- }
- EditorGUI.indentLevel--;
- }
- }
- /************************************************************************************************************************/
- private static void DoBindingGUI(ref Rect area, SerializedProperty bindings, int index, GUIContent label)
- {
- var indentLevel = EditorGUI.indentLevel;
- if (string.IsNullOrEmpty(label.text))
- EditorGUI.indentLevel = 0;
- var binding = bindings.GetArrayElementAtIndex(index);
- EditorGUI.PropertyField(area, binding, label);
- NextVerticalArea(ref area);
- EditorGUI.indentLevel = indentLevel;
- }
- /************************************************************************************************************************/
- private void GetFields(
- SerializedProperty root,
- out SerializedProperty mode,
- out SerializedProperty bindings)
- {
- mode = root.FindPropertyRelative(ControllerState.SerializableParameterBindings.ModeFieldName);
- bindings = root.FindPropertyRelative(ControllerState.SerializableParameterBindings.BindingsFieldName);
- }
- /************************************************************************************************************************/
- private string GetContextParameterList(SerializedProperty property)
- {
- var path = property.propertyPath;
- var lastDot = path.LastIndexOf('.');
- if (lastDot < 0)
- return null;
- path = path[..(lastDot + 1)] + ControllerTransition.ControllerFieldName;
- property = property.serializedObject.FindProperty(path);
- if (property == null ||
- property.objectReferenceValue is not AnimatorController animatorController)
- return null;
- return GetParameterList(animatorController);
- }
- private readonly Dictionary<AnimatorController, string>
- ControllerToParameterList = new();
- private string GetParameterList(AnimatorController animatorController)
- {
- if (animatorController == null)
- return null;
- if (ControllerToParameterList.TryGetValue(animatorController, out var parameterList))
- return parameterList;
- var text = StringBuilderPool.Instance.Acquire();
- var parameters = animatorController.parameters;
- if (parameters.Length > 0)
- {
- text.Append("\n\nParameters in ")
- .Append(animatorController.name)
- .Append(':');
- for (int i = 0; i < parameters.Length; i++)
- {
- var parameter = parameters[i];
- text.Append("\n� ")
- .Append(parameter.type)
- .Append(' ')
- .Append(parameter.name);
- }
- }
- parameterList = text.ReleaseToString();
- ControllerToParameterList.Add(animatorController, parameterList);
- return parameterList;
- }
- /************************************************************************************************************************/
- }
- }
- #endif
|