This commit is contained in:
陈思海 2025-07-29 11:05:15 +08:00
parent 8b10f98116
commit 1b8335be22

View File

@ -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<Animation>() : null;
var animator = graphic != null ? graphic.GetComponent<Animator>() : 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<Animation>() : null;
var animator = graphic != null ? graphic.GetComponent<Animator>() : 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<Animation>() : null;
var animator = graphic != null ? graphic.GetComponent<Animator>() : 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<Animator>();
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;