cvr-props/Assets/ABI.CCK/Scripts/Editor/CCK_AnimatorDriverEditor.cs
2023-07-30 01:20:46 +02:00

353 lines
No EOL
15 KiB
C#
Executable file

using System;
using System.Collections.Generic;
using ABI.CCK.Components;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using AnimatorController = UnityEditor.Animations.AnimatorController;
using AnimatorControllerParameterType = UnityEngine.AnimatorControllerParameterType;
[CustomEditor(typeof(ABI.CCK.Components.AnimatorDriver))]
public class CCK_AnimatorDriverEditor : UnityEditor.Editor
{
private AnimatorDriver _animatorDriver;
private ReorderableList _onEnterList;
private ReorderableList _onExitList;
private List<string> animatorParamNames = new List<string>();
private List<string> animatorParamNamesDisplay = new List<string>();
private List<AnimatorDriverTask.ParameterType> animatorParamTypes = new List<AnimatorDriverTask.ParameterType>();
public override void OnInspectorGUI()
{
if (_animatorDriver == null) _animatorDriver = (AnimatorDriver) target;
animatorParamNames.Clear();
animatorParamNamesDisplay.Clear();
animatorParamTypes.Clear();
animatorParamNames.Add("- None -");
animatorParamNamesDisplay.Add("- None -");
animatorParamTypes.Add(AnimatorDriverTask.ParameterType.None);
var behaviorContext = AnimatorController.FindStateMachineBehaviourContext(_animatorDriver);
if (behaviorContext.Length > 0)
{
var controller = behaviorContext[0].animatorController;
foreach (var parameter in controller.parameters)
{
switch (parameter.type)
{
case AnimatorControllerParameterType.Bool:
animatorParamNames.Add($"{parameter.name}");
animatorParamNamesDisplay.Add($"{parameter.name} (Bool)");
animatorParamTypes.Add(AnimatorDriverTask.ParameterType.Bool);
break;
case AnimatorControllerParameterType.Float:
animatorParamNames.Add($"{parameter.name}");
animatorParamNamesDisplay.Add($"{parameter.name} (Float)");
animatorParamTypes.Add(AnimatorDriverTask.ParameterType.Float);
break;
case AnimatorControllerParameterType.Int:
animatorParamNames.Add($"{parameter.name}");
animatorParamNamesDisplay.Add($"{parameter.name} (Int)");
animatorParamTypes.Add(AnimatorDriverTask.ParameterType.Int);
break;
case AnimatorControllerParameterType.Trigger:
animatorParamNames.Add($"{parameter.name}");
animatorParamNamesDisplay.Add($"{parameter.name} (Trigger)");
animatorParamTypes.Add(AnimatorDriverTask.ParameterType.Trigger);
break;
}
}
}
if (_onEnterList == null)
{
_onEnterList = new ReorderableList(_animatorDriver.EnterTasks, typeof(AnimatorDriverTask),
true, true, true, true);
_onEnterList.drawHeaderCallback = OnDrawHeaderTaskEnter;
_onEnterList.drawElementCallback = OnDrawElementTaskEnter;
_onEnterList.elementHeightCallback = OnHeightElementTaskEnter;
}
_onEnterList.DoLayoutList();
if (_onExitList == null)
{
_onExitList = new ReorderableList(_animatorDriver.ExitTasks, typeof(AnimatorDriverTask),
true, true, true, true);
_onExitList.drawHeaderCallback = OnDrawHeaderTaskExit;
_onExitList.drawElementCallback = OnDrawElementTaskExit;
_onExitList.elementHeightCallback = OnHeightElementTaskExit;
}
_onExitList.DoLayoutList();
}
private void OnDrawHeaderTaskEnter(Rect rect)
{
Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
GUI.Label(_rect, "On Enter State");
}
private void OnDrawElementTaskEnter(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _animatorDriver.EnterTasks.Count) return;
AnimatorDriverTask element = _animatorDriver.EnterTasks[index];
RenderTask(rect, element);
}
private float OnHeightElementTaskEnter(int index)
{
int length = 3;
if (index > _animatorDriver.EnterTasks.Count) return 1.25f * length * EditorGUIUtility.singleLineHeight;
AnimatorDriverTask task = _animatorDriver.EnterTasks[index];
return (length + TaskHeight(task)) * 1.25f * EditorGUIUtility.singleLineHeight;
}
private void OnDrawHeaderTaskExit(Rect rect)
{
Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
GUI.Label(_rect, "On Exit State");
}
private void OnDrawElementTaskExit(Rect rect, int index, bool isactive, bool isfocused)
{
if (index > _animatorDriver.ExitTasks.Count) return;
AnimatorDriverTask element = _animatorDriver.ExitTasks[index];
RenderTask(rect, element);
}
private float OnHeightElementTaskExit(int index)
{
int length = 3;
if (index > _animatorDriver.ExitTasks.Count) return 1.25f * length * EditorGUIUtility.singleLineHeight;
AnimatorDriverTask task = _animatorDriver.ExitTasks[index];
return (length + TaskHeight(task)) * 1.25f * EditorGUIUtility.singleLineHeight;
}
private int TaskHeight(AnimatorDriverTask task)
{
int length = 0;
switch (task.aType)
{
case AnimatorDriverTask.SourceType.Static:
case AnimatorDriverTask.SourceType.Parameter:
length += 1;
break;
case AnimatorDriverTask.SourceType.Random:
length += 2;
break;
}
if (task.op != AnimatorDriverTask.Operator.Set)
{
length += 1;
switch (task.bType)
{
case AnimatorDriverTask.SourceType.Static:
case AnimatorDriverTask.SourceType.Parameter:
length += 1;
break;
case AnimatorDriverTask.SourceType.Random:
length += 2;
break;
}
}
length += 1;
return length;
}
private void RenderTask(Rect rect, AnimatorDriverTask task)
{
string formulaDisplay = "";
Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
int parameterIndex = Math.Max(animatorParamNames.FindIndex(m => m == task.targetName), 0);
EditorGUI.LabelField(_rect, "Parameter");
_rect.x += 100;
_rect.width = rect.width - 100;
int selectedIndex = EditorGUI.Popup(_rect, parameterIndex, animatorParamNamesDisplay.ToArray());
task.targetType = animatorParamTypes[selectedIndex];
task.targetName = animatorParamNames[selectedIndex];
formulaDisplay = $"{task.targetName} = ";
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "Operation");
_rect.x += 100;
_rect.width = rect.width - 100;
task.op = (AnimatorDriverTask.Operator) EditorGUI.EnumPopup(_rect, task.op);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "A Type");
_rect.x += 100;
_rect.width = rect.width - 100;
task.aType = (AnimatorDriverTask.SourceType) EditorGUI.EnumPopup(_rect, task.aType);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
switch (task.aType)
{
case AnimatorDriverTask.SourceType.Static:
EditorGUI.LabelField(_rect, "A Value");
_rect.x += 100;
_rect.width = rect.width - 100;
task.aValue = EditorGUI.FloatField(_rect, task.aValue);
formulaDisplay += $"{task.aValue} ";
break;
case AnimatorDriverTask.SourceType.Parameter:
parameterIndex = Math.Max(animatorParamNames.FindIndex(m => m == task.aName), 0);
EditorGUI.LabelField(_rect, "Parameter A");
_rect.x += 100;
_rect.width = rect.width - 100;
selectedIndex = EditorGUI.Popup(_rect, parameterIndex, animatorParamNamesDisplay.ToArray());
task.aParamType = animatorParamTypes[selectedIndex];
task.aName = animatorParamNames[selectedIndex];
formulaDisplay += $"{task.aName} ";
break;
case AnimatorDriverTask.SourceType.Random:
EditorGUI.LabelField(_rect, "A Min");
_rect.x += 100;
_rect.width = rect.width - 100;
task.aValue = EditorGUI.FloatField(_rect, task.aValue);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "A Max");
_rect.x += 100;
_rect.width = rect.width - 100;
task.aMax = Convert.ToSingle(EditorGUI.TextField(_rect, task.aMax.ToString()));
formulaDisplay += $"Rand({task.aValue}, {task.aMax}) ";
break;
}
if (task.op != AnimatorDriverTask.Operator.Set)
{
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
switch (task.op)
{
case AnimatorDriverTask.Operator.Addition:
formulaDisplay += "+ ";
break;
case AnimatorDriverTask.Operator.Subtraction:
formulaDisplay += "- ";
break;
case AnimatorDriverTask.Operator.Multiplication:
formulaDisplay += "* ";
break;
case AnimatorDriverTask.Operator.Division:
formulaDisplay += "/ ";
break;
case AnimatorDriverTask.Operator.Modulo:
formulaDisplay += "% ";
break;
case AnimatorDriverTask.Operator.Power:
formulaDisplay += "pow ";
break;
case AnimatorDriverTask.Operator.Log:
formulaDisplay += "log ";
break;
case AnimatorDriverTask.Operator.Equal:
formulaDisplay += "== ";
break;
case AnimatorDriverTask.Operator.LessThen:
formulaDisplay += "< ";
break;
case AnimatorDriverTask.Operator.LessEqual:
formulaDisplay += "<= ";
break;
case AnimatorDriverTask.Operator.MoreThen:
formulaDisplay += "> ";
break;
case AnimatorDriverTask.Operator.MoreEqual:
formulaDisplay += ">= ";
break;
case AnimatorDriverTask.Operator.NotEqual:
formulaDisplay += "!= ";
break;
}
EditorGUI.LabelField(_rect, "B Type");
_rect.x += 100;
_rect.width = rect.width - 100;
task.bType = (AnimatorDriverTask.SourceType) EditorGUI.EnumPopup(_rect, task.bType);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
switch (task.bType)
{
case AnimatorDriverTask.SourceType.Static:
EditorGUI.LabelField(_rect, "B Value");
_rect.x += 100;
_rect.width = rect.width - 100;
task.bValue = EditorGUI.FloatField(_rect, task.bValue);
formulaDisplay += $"{task.bValue} ";
break;
case AnimatorDriverTask.SourceType.Parameter:
parameterIndex = Math.Max(animatorParamNames.FindIndex(m => m == task.bName), 0);
EditorGUI.LabelField(_rect, "Parameter B");
_rect.x += 100;
_rect.width = rect.width - 100;
selectedIndex = EditorGUI.Popup(_rect, parameterIndex, animatorParamNamesDisplay.ToArray());
task.bParamType = animatorParamTypes[selectedIndex];
task.bName = animatorParamNames[selectedIndex];
formulaDisplay += $"{task.bName} ";
break;
case AnimatorDriverTask.SourceType.Random:
EditorGUI.LabelField(_rect, "B Min");
_rect.x += 100;
_rect.width = rect.width - 100;
task.bValue = EditorGUI.FloatField(_rect, task.bValue);
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, "B Max");
_rect.x += 100;
_rect.width = rect.width - 100;
task.bMax = Convert.ToSingle(EditorGUI.TextField(_rect, task.bMax.ToString()));
formulaDisplay += $"Rand({task.bValue}, {task.bMax}) ";
break;
}
}
var boldtext = new GUIStyle (GUI.skin.label);
boldtext.fontStyle = FontStyle.Bold;
rect.y += EditorGUIUtility.singleLineHeight * 1.25f;
_rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
EditorGUI.LabelField(_rect, task.targetName == "- None -"?"Parameter = A":formulaDisplay, boldtext);
}
}