204 lines
7.0 KiB
C#
204 lines
7.0 KiB
C#
// 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
|
|
|