diff --git a/Editor/UX/UXButtonEditor.cs b/Editor/UX/UXButtonEditor.cs index c95cf92..5460905 100644 --- a/Editor/UX/UXButtonEditor.cs +++ b/Editor/UX/UXButtonEditor.cs @@ -6,6 +6,7 @@ using UnityEditorInternal; using UnityEditor.UI; using UnityEngine; using UnityEngine.UI; +using AnimatorControllerParameterType = UnityEngine.AnimatorControllerParameterType; [CanEditMultipleObjects] [CustomEditor(typeof(UXButton), true)] @@ -296,7 +297,7 @@ internal class UXButtonEditor : Editor SerializedProperty targetGraphic = transitionData.FindPropertyRelative("targetGraphic"); var graphic = targetGraphic.objectReferenceValue as Graphic; - var animation = graphic != null ? graphic.GetComponent() : null; + var animator = graphic != null ? graphic.GetComponent() : null; switch (currentTransition) { @@ -307,7 +308,7 @@ internal class UXButtonEditor : Editor if (!(graphic is Image)) height += EditorGUIUtility.singleLineHeight; break; case Selectable.Transition.Animation: - if (animation == null) height += EditorGUIUtility.singleLineHeight; + if (animator == null) height += EditorGUIUtility.singleLineHeight; break; } @@ -352,7 +353,7 @@ internal class UXButtonEditor : Editor y += lineHeight + spacing; var graphic = targetGraphic.objectReferenceValue as Graphic; - var animation = graphic != null ? graphic.GetComponent() : null; + var animator = graphic != null ? graphic.GetComponent() : null; switch (currentTransition) { @@ -376,7 +377,7 @@ internal class UXButtonEditor : Editor break; case Selectable.Transition.Animation: - if (animation == null) + if (animator == null) { Rect warningRect = new Rect(position.x, y, position.width, lineHeight); EditorGUI.HelpBox(warningRect, "需要Animation || Animator组件来使用动画切换", MessageType.Warning); @@ -425,7 +426,7 @@ internal class UXButtonEditor : Editor var currentTransition = GetTransition(transition); - var animation = graphic != null ? graphic.GetComponent() : null; + var animator = graphic != null ? graphic.GetComponent() : null; switch (currentTransition) { case Selectable.Transition.ColorTint: @@ -437,7 +438,7 @@ internal class UXButtonEditor : Editor EditorGUILayout.HelpBox("需要Image组件来使用精灵切换", MessageType.Warning); break; case Selectable.Transition.Animation: - if (animation == null) + if (animator == null) EditorGUILayout.HelpBox("需要Animation || Animator组件来使用动画切换", MessageType.Warning); break; } @@ -453,6 +454,21 @@ internal class UXButtonEditor : Editor break; case Selectable.Transition.Animation: EditorGUILayout.PropertyField(m_TransitionData.FindPropertyRelative("animationTriggers")); + if (animator == null || animator.runtimeAnimatorController == null) + { + if (GUILayout.Button("Auto Generate Animation")) + { + var controller = GenerateSelectableAnimatorContoller((target as Selectable).animationTriggers, target as Selectable); + if (controller != null) + { + if (animator == null) + animator = (target as Selectable).gameObject.AddComponent(); + + UnityEditor.Animations.AnimatorController.SetAnimatorController(animator, controller); + } + } + } + break; } @@ -461,6 +477,59 @@ internal class UXButtonEditor : Editor GUILayout.EndVertical(); } + private static UnityEditor.Animations.AnimatorController GenerateSelectableAnimatorContoller(AnimationTriggers animationTriggers, Selectable target) + { + if (target == null) + return null; + + var path = GetSaveControllerPath(target); + if (string.IsNullOrEmpty(path)) + return null; + + var normalName = string.IsNullOrEmpty(animationTriggers.normalTrigger) ? "Normal" : animationTriggers.normalTrigger; + var highlightedName = string.IsNullOrEmpty(animationTriggers.highlightedTrigger) ? "Highlighted" : animationTriggers.highlightedTrigger; + var pressedName = string.IsNullOrEmpty(animationTriggers.pressedTrigger) ? "Pressed" : animationTriggers.pressedTrigger; + var selectedName = string.IsNullOrEmpty(animationTriggers.selectedTrigger) ? "Selected" : animationTriggers.selectedTrigger; + var disabledName = string.IsNullOrEmpty(animationTriggers.disabledTrigger) ? "Disabled" : animationTriggers.disabledTrigger; + + var controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(path); + GenerateTriggerableTransition(normalName, controller); + GenerateTriggerableTransition(highlightedName, controller); + GenerateTriggerableTransition(pressedName, controller); + GenerateTriggerableTransition(selectedName, controller); + GenerateTriggerableTransition(disabledName, controller); + + AssetDatabase.ImportAsset(path); + + return controller; + } + + private static AnimationClip GenerateTriggerableTransition(string name, UnityEditor.Animations.AnimatorController controller) + { + // Create the clip + var clip = UnityEditor.Animations.AnimatorController.AllocateAnimatorClip(name); + AssetDatabase.AddObjectToAsset(clip, controller); + + // Create a state in the animatior controller for this clip + var state = controller.AddMotion(clip); + + // Add a transition property + controller.AddParameter(name, AnimatorControllerParameterType.Trigger); + + // Add an any state transition + var stateMachine = controller.layers[0].stateMachine; + var transition = stateMachine.AddAnyStateTransition(state); + transition.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, name); + return clip; + } + + private static string GetSaveControllerPath(Selectable target) + { + var defaultName = target.gameObject.name; + var message = string.Format("Create a new animator for the game object '{0}':", defaultName); + return EditorUtility.SaveFilePanelInProject("New Animation Contoller", defaultName, "controller", message); + } + void CheckAndSetColorDefaults(SerializedProperty colorBlock, SerializedProperty targetGraphic) { bool isDirty = false;