123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
- #if UNITY_EDITOR && UNITY_IMGUI
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- namespace Animancer.Editor
- {
- /// <summary>[Editor-Only] Draws the Inspector GUI for an <see cref="AnimancerState"/>.</summary>
- /// https://kybernetik.com.au/animancer/api/Animancer.Editor/ParametizedAnimancerStateDrawer_1
- [CustomGUI(typeof(ManualMixerState))]
- public class ParametizedAnimancerStateDrawer<T> : AnimancerStateDrawer<T>
- where T : AnimancerState, IParametizedState
- {
- /************************************************************************************************************************/
- /// <inheritdoc/>
- protected override void DoDetailsGUI()
- {
- base.DoDetailsGUI();
- if (!IsExpanded)
- return;
- EditorGUI.indentLevel++;
- var parameters = ListPool.Acquire<StateParameterDetails>();
- Value.GetParameters(parameters);
- DoParametersGUI(parameters);
- ListPool.Release(parameters);
- EditorGUI.indentLevel--;
- }
- /************************************************************************************************************************/
- /// <summary>Draws fields for all `parameters`.</summary>
- private void DoParametersGUI(List<StateParameterDetails> parameters)
- {
- if (parameters.Count == 0)
- return;
- var labelWidth = EditorGUIUtility.labelWidth;
- EditorGUIUtility.labelWidth -= AnimancerGUI.IndentSize;
- EditorGUI.BeginChangeCheck();
- for (int i = 0; i < parameters.Count; i++)
- parameters[i] = DoParameterGUI(i, parameters[i]);
- EditorGUIUtility.labelWidth = labelWidth;
- if (EditorGUI.EndChangeCheck())
- Value.SetParameters(parameters);
- }
- /************************************************************************************************************************/
- /// <summary>Draws fields for the `parameter`.</summary>
- private StateParameterDetails DoParameterGUI(int index, StateParameterDetails parameter)
- {
- var area = AnimancerGUI.LayoutSingleLineRect(AnimancerGUI.SpacingMode.Before);
- var indentLevel = EditorGUI.indentLevel;
- var labelWidth = EditorGUIUtility.labelWidth;
- var label = parameter.label;
- if (parameter.SupportsBinding && Value.Graph.HasParameters)
- {
- area = EditorGUI.IndentedRect(area);
- EditorGUI.indentLevel = 0;
- parameter = DoBindingGUI(ref area, index, parameter, ref label);
- }
- else
- {
- EditorGUIUtility.labelWidth += AnimancerGUI.IndentSize;
- }
- switch (parameter.type)
- {
- case AnimatorControllerParameterType.Float:
- parameter.value = EditorGUI.FloatField(area, label, (float)parameter.value);
- break;
- case AnimatorControllerParameterType.Int:
- parameter.value = EditorGUI.IntField(area, label, (int)parameter.value);
- break;
- case AnimatorControllerParameterType.Bool:
- parameter.value = EditorGUI.Toggle(area, label, (bool)parameter.value);
- break;
- case AnimatorControllerParameterType.Trigger:
- parameter.value = EditorGUI.Toggle(area, label, (bool)parameter.value, EditorStyles.radioButton);
- break;
- default:
- EditorGUI.LabelField(area, label, "Unsupported Type: " + parameter.type);
- break;
- }
- EditorGUI.indentLevel = indentLevel;
- EditorGUIUtility.labelWidth = labelWidth;
- return parameter;
- }
- /************************************************************************************************************************/
- /// <summary>Draws a dropdown for the `parameter`'s name binding.</summary>
- private StateParameterDetails DoBindingGUI(
- ref Rect area,
- int index,
- StateParameterDetails parameter,
- ref string fieldLabel)
- {
- if (!parameter.SupportsBinding)
- return parameter;
- var spacing = AnimancerGUI.StandardSpacing;
- float width;
- if (string.IsNullOrEmpty(parameter.name))
- {
- width = area.height + spacing;
- EditorGUIUtility.labelWidth -= width + AnimancerGUI.IndentSize + spacing;
- }
- else
- {
- width = EditorGUIUtility.labelWidth - AnimancerGUI.IndentSize;
- fieldLabel = "";
- }
- var labelArea = AnimancerGUI.StealFromLeft(
- ref area,
- width,
- spacing);
- using (var label = PooledGUIContent.Acquire(parameter.name))
- {
- if (EditorGUI.DropdownButton(labelArea, label, FocusType.Passive))
- ShowBindingSelectionMenu(labelArea, index, parameter.name);
- }
- return parameter;
- }
- /************************************************************************************************************************/
- /// <summary>Shows a context menu for selecting the parameter binding.</summary>
- private void ShowBindingSelectionMenu(Rect area, int index, string currentName)
- {
- var menu = new GenericMenu();
- menu.AddItem(
- new("None"),
- string.IsNullOrEmpty(currentName),
- () => SetParameterName(index, null));
- menu.AddSeparator("");
- foreach (var parameter in Value.Graph.Parameters)
- {
- if (parameter.ValueType != typeof(float))
- continue;
- var name = parameter.Key;
- menu.AddItem(
- new(name),
- name == currentName,
- () => SetParameterName(index, name));
- }
- menu.DropDown(area);
- }
- /************************************************************************************************************************/
- /// <summary>Sets the name binding of the specified parameter.</summary>
- private void SetParameterName(int index, string name)
- {
- var parameters = ListPool.Acquire<StateParameterDetails>();
- Value.GetParameters(parameters);
- var modify = parameters[index];
- modify.name = name;
- parameters[index] = modify;
- Value.SetParameters(parameters);
- ListPool.Release(parameters);
- }
- /************************************************************************************************************************/
- }
- }
- #endif
|