TransitionLibrarySelectionEditor.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using Animancer.TransitionLibraries;
  4. using System;
  5. using UnityEditor;
  6. using UnityEngine;
  7. using Object = UnityEngine.Object;
  8. namespace Animancer.Editor.TransitionLibraries
  9. {
  10. /// <summary>[Editor-Only]
  11. /// A custom Inspector for <see cref="TransitionLibrarySelection"/>.
  12. /// </summary>
  13. /// https://kybernetik.com.au/animancer/api/Animancer.Editor.TransitionLibraries/TransitionLibrarySelectionEditor
  14. [CustomEditor(typeof(TransitionLibrarySelection), true)]
  15. public class TransitionLibrarySelectionEditor : UnityEditor.Editor
  16. {
  17. /************************************************************************************************************************/
  18. /// <summary>Casts the <see cref="UnityEditor.Editor.target"/>.</summary>
  19. public TransitionLibrarySelection Target
  20. => target as TransitionLibrarySelection;
  21. /************************************************************************************************************************/
  22. /// <inheritdoc/>
  23. public override void OnInspectorGUI()
  24. {
  25. var target = Target;
  26. if (target == null || !target.Validate())
  27. return;
  28. EditorGUI.BeginChangeCheck();
  29. switch (target.Type)
  30. {
  31. case TransitionLibrarySelection.SelectionType.Library:
  32. DoNestedEditorGUI(target.Selected as TransitionLibraryAsset, "Transition Library");
  33. break;
  34. case TransitionLibrarySelection.SelectionType.FromTransition:
  35. case TransitionLibrarySelection.SelectionType.ToTransition:
  36. DoTransitionGUI(target.Selected as TransitionAssetBase);
  37. break;
  38. case TransitionLibrarySelection.SelectionType.Modifier:
  39. DoModifierGUI(target, (TransitionModifierDefinition)target.Selected);
  40. break;
  41. default:
  42. target.Deselect();
  43. break;
  44. }
  45. if (EditorGUI.EndChangeCheck())
  46. target.Window.Repaint();
  47. }
  48. /************************************************************************************************************************/
  49. #region Nested Editor
  50. /************************************************************************************************************************/
  51. [NonSerialized] private readonly CachedEditor NestedEditor = new();
  52. [NonSerialized] private readonly CachedEditor NestedEditor2 = new();
  53. /************************************************************************************************************************/
  54. /// <summary>Draws the <see cref="UnityEditor.Editor"/> for the `target`.</summary>
  55. private void DoNestedEditorGUI<T>(T target, string referenceLabel)
  56. where T : Object
  57. {
  58. using (new EditorGUI.DisabledScope(true))
  59. AnimancerGUI.DoObjectFieldGUI(referenceLabel, target, false);
  60. var editor = NestedEditor.GetEditor(target);
  61. if (editor != null)
  62. editor.OnInspectorGUI();
  63. }
  64. /************************************************************************************************************************/
  65. /// <summary>Cleans up any nested editors.</summary>
  66. protected virtual void OnDestroy()
  67. {
  68. NestedEditor.Dispose();
  69. NestedEditor2.Dispose();
  70. }
  71. /************************************************************************************************************************/
  72. #endregion
  73. /************************************************************************************************************************/
  74. #region Transitions
  75. /************************************************************************************************************************/
  76. /// <summary>Draws the GUI for the `transition`.</summary>
  77. private void DoTransitionGUI(
  78. TransitionAssetBase transition)
  79. {
  80. DoTransitionNameGUI(transition);
  81. DoNestedEditorGUI(transition, "Transition Asset");
  82. }
  83. /************************************************************************************************************************/
  84. /// <summary>Draws a field for editing the name of the `transition`.</summary>
  85. private void DoTransitionNameGUI(
  86. TransitionAssetBase transition)
  87. {
  88. var isSubAsset = AssetDatabase.IsSubAsset(transition);
  89. var isMainAsset = !isSubAsset && AssetDatabase.IsMainAsset(transition);
  90. var label = isSubAsset
  91. ? "Sub-Asset Name"
  92. : isMainAsset
  93. ? "File Name"
  94. : "Name";
  95. EditorGUI.BeginChangeCheck();
  96. var name = TransitionModifierTableGUI.GetTransitionName(transition);
  97. name = EditorGUILayout.DelayedTextField(label, name);
  98. if (EditorGUI.EndChangeCheck() && transition != null)
  99. {
  100. transition.SetName(name);
  101. if (isSubAsset)
  102. {
  103. AssetDatabase.SaveAssets();
  104. }
  105. else if (isMainAsset)
  106. {
  107. AssetDatabase.RenameAsset(
  108. AssetDatabase.GetAssetPath(transition),
  109. name);
  110. }
  111. }
  112. }
  113. /************************************************************************************************************************/
  114. #endregion
  115. /************************************************************************************************************************/
  116. #region Modifiers
  117. /************************************************************************************************************************/
  118. private static readonly BoolPref
  119. IsFromExpanded = new($"{nameof(TransitionLibrarySelectionEditor)}.{nameof(IsFromExpanded)}"),
  120. IsToExpanded = new($"{nameof(TransitionLibrarySelectionEditor)}.{nameof(IsToExpanded)}");
  121. /************************************************************************************************************************/
  122. /// <summary>Draws the GUI for the `modifier`.</summary>
  123. private void DoModifierGUI(
  124. TransitionLibrarySelection selection,
  125. TransitionModifierDefinition modifier)
  126. {
  127. var library = selection.Window.Data;
  128. DoTransitionField(library, NestedEditor, IsFromExpanded, modifier.FromIndex, "From");
  129. DoTransitionField(library, NestedEditor2, IsToExpanded, modifier.ToIndex, "To");
  130. var area = AnimancerGUI.LayoutSingleLineRect();
  131. TransitionModifierTableGUI.DoFadeDurationGUI(
  132. area,
  133. selection.Window,
  134. modifier.FromIndex,
  135. modifier.ToIndex,
  136. "Fade Duration");
  137. }
  138. /************************************************************************************************************************/
  139. /// <summary>Draws the GUI for a transition.</summary>
  140. private TransitionAssetBase DoTransitionField(
  141. TransitionLibraryDefinition library,
  142. CachedEditor cachedEditor,
  143. BoolPref isExpanded,
  144. int transitionIndex,
  145. string label)
  146. {
  147. library.TryGetTransition(transitionIndex, out var transition);
  148. var area = AnimancerGUI.LayoutSingleLineRect(AnimancerGUI.SpacingMode.After);
  149. var labelArea = area;
  150. labelArea.width = EditorGUIUtility.labelWidth;
  151. isExpanded.Value = EditorGUI.Foldout(labelArea, isExpanded, GUIContent.none, true);
  152. var enabled = GUI.enabled;
  153. GUI.enabled = false;
  154. AnimancerGUI.DoObjectFieldGUI(area, label, transition, false);
  155. GUI.enabled = enabled;
  156. if (isExpanded)
  157. {
  158. GUILayout.BeginVertical(GUI.skin.box);
  159. var editor = cachedEditor.GetEditor(transition);
  160. editor.OnInspectorGUI();
  161. GUILayout.EndVertical();
  162. }
  163. return transition;
  164. }
  165. /************************************************************************************************************************/
  166. #endregion
  167. /************************************************************************************************************************/
  168. }
  169. }
  170. #endif