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 animatorParamNames = new List(); private List animatorParamNamesDisplay = new List(); private List animatorParamTypes = new List(); 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); } }