217 lines
8.6 KiB
C#
217 lines
8.6 KiB
C#
// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
using Animancer.TransitionLibraries;
|
|
using System;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace Animancer.Editor.TransitionLibraries
|
|
{
|
|
/// <summary>[Editor-Only]
|
|
/// A custom Inspector for <see cref="TransitionLibrarySelection"/>.
|
|
/// </summary>
|
|
/// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibrarySelectionEditor
|
|
[CustomEditor(typeof(TransitionLibrarySelection), true)]
|
|
public class TransitionLibrarySelectionEditor : UnityEditor.Editor
|
|
{
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Casts the <see cref="UnityEditor.Editor.target"/>.</summary>
|
|
public TransitionLibrarySelection Target
|
|
=> target as TransitionLibrarySelection;
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <inheritdoc/>
|
|
public override void OnInspectorGUI()
|
|
{
|
|
var target = Target;
|
|
if (target == null || !target.Validate())
|
|
return;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
switch (target.Type)
|
|
{
|
|
case TransitionLibrarySelection.SelectionType.Library:
|
|
DoNestedEditorGUI(target.Selected as TransitionLibraryAsset, "Transition Library");
|
|
break;
|
|
|
|
case TransitionLibrarySelection.SelectionType.FromTransition:
|
|
case TransitionLibrarySelection.SelectionType.ToTransition:
|
|
DoTransitionGUI(target.Selected as TransitionAssetBase);
|
|
break;
|
|
|
|
case TransitionLibrarySelection.SelectionType.Modifier:
|
|
DoModifierGUI(target, (TransitionModifierDefinition)target.Selected);
|
|
break;
|
|
|
|
default:
|
|
target.Deselect();
|
|
break;
|
|
}
|
|
|
|
if (EditorGUI.EndChangeCheck())
|
|
target.Window.Repaint();
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
#region Nested Editor
|
|
/************************************************************************************************************************/
|
|
|
|
[NonSerialized] private readonly CachedEditor NestedEditor = new();
|
|
[NonSerialized] private readonly CachedEditor NestedEditor2 = new();
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Draws the <see cref="UnityEditor.Editor"/> for the `target`.</summary>
|
|
private void DoNestedEditorGUI<T>(T target, string referenceLabel)
|
|
where T : Object
|
|
{
|
|
using (new EditorGUI.DisabledScope(true))
|
|
AnimancerGUI.DoObjectFieldGUI(referenceLabel, target, false);
|
|
|
|
var editor = NestedEditor.GetEditor(target);
|
|
if (editor != null)
|
|
editor.OnInspectorGUI();
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Cleans up any nested editors.</summary>
|
|
protected virtual void OnDestroy()
|
|
{
|
|
NestedEditor.Dispose();
|
|
NestedEditor2.Dispose();
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
#endregion
|
|
/************************************************************************************************************************/
|
|
#region Transitions
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Draws the GUI for the `transition`.</summary>
|
|
private void DoTransitionGUI(
|
|
TransitionAssetBase transition)
|
|
{
|
|
DoTransitionNameGUI(transition);
|
|
DoNestedEditorGUI(transition, "Transition Asset");
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Draws a field for editing the name of the `transition`.</summary>
|
|
private void DoTransitionNameGUI(
|
|
TransitionAssetBase transition)
|
|
{
|
|
var isSubAsset = AssetDatabase.IsSubAsset(transition);
|
|
var isMainAsset = !isSubAsset && AssetDatabase.IsMainAsset(transition);
|
|
var label = isSubAsset
|
|
? "Sub-Asset Name"
|
|
: isMainAsset
|
|
? "File Name"
|
|
: "Name";
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
var name = TransitionModifierTableGUI.GetTransitionName(transition);
|
|
name = EditorGUILayout.DelayedTextField(label, name);
|
|
|
|
if (EditorGUI.EndChangeCheck() && transition != null)
|
|
{
|
|
transition.SetName(name);
|
|
|
|
if (isSubAsset)
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
else if (isMainAsset)
|
|
{
|
|
AssetDatabase.RenameAsset(
|
|
AssetDatabase.GetAssetPath(transition),
|
|
name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
#endregion
|
|
/************************************************************************************************************************/
|
|
#region Modifiers
|
|
/************************************************************************************************************************/
|
|
|
|
private static readonly BoolPref
|
|
IsFromExpanded = new($"{nameof(TransitionLibrarySelectionEditor)}.{nameof(IsFromExpanded)}"),
|
|
IsToExpanded = new($"{nameof(TransitionLibrarySelectionEditor)}.{nameof(IsToExpanded)}");
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Draws the GUI for the `modifier`.</summary>
|
|
private void DoModifierGUI(
|
|
TransitionLibrarySelection selection,
|
|
TransitionModifierDefinition modifier)
|
|
{
|
|
var library = selection.Window.Data;
|
|
DoTransitionField(library, NestedEditor, IsFromExpanded, modifier.FromIndex, "From");
|
|
DoTransitionField(library, NestedEditor2, IsToExpanded, modifier.ToIndex, "To");
|
|
|
|
var area = AnimancerGUI.LayoutSingleLineRect();
|
|
TransitionModifierTableGUI.DoFadeDurationGUI(
|
|
area,
|
|
selection.Window,
|
|
modifier.FromIndex,
|
|
modifier.ToIndex,
|
|
"Fade Duration");
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>Draws the GUI for a transition.</summary>
|
|
private TransitionAssetBase DoTransitionField(
|
|
TransitionLibraryDefinition library,
|
|
CachedEditor cachedEditor,
|
|
BoolPref isExpanded,
|
|
int transitionIndex,
|
|
string label)
|
|
{
|
|
library.TryGetTransition(transitionIndex, out var transition);
|
|
|
|
var area = AnimancerGUI.LayoutSingleLineRect(AnimancerGUI.SpacingMode.After);
|
|
var labelArea = area;
|
|
labelArea.width = EditorGUIUtility.labelWidth;
|
|
|
|
isExpanded.Value = EditorGUI.Foldout(labelArea, isExpanded, GUIContent.none, true);
|
|
|
|
var enabled = GUI.enabled;
|
|
GUI.enabled = false;
|
|
|
|
AnimancerGUI.DoObjectFieldGUI(area, label, transition, false);
|
|
|
|
GUI.enabled = enabled;
|
|
|
|
if (isExpanded)
|
|
{
|
|
GUILayout.BeginVertical(GUI.skin.box);
|
|
|
|
var editor = cachedEditor.GetEditor(transition);
|
|
editor.OnInspectorGUI();
|
|
|
|
GUILayout.EndVertical();
|
|
}
|
|
|
|
return transition;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
#endregion
|
|
/************************************************************************************************************************/
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|