using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using DG.Tweening; [CustomEditor(typeof(AnimationUI))] public class AnimationUIEditor : Editor { private List foldouts = new List(); // 存储折叠状态 string[] OnenableOpens = new string[] { "一唤醒就播放", "按钮播放","消失前播放" }; string[] loopTypeOptions = new string[] { "重新开始", "往返", "叠加" }; public override void OnInspectorGUI() { // 获取目标脚本的引用 AnimationUI myScript = (AnimationUI)target; EditorGUILayout.Space(); // 初始化折叠列表的大小 EnsureFoldoutListSize(myScript); // 标记是否需要删除某个效果 int deleteIndex = -1; bool isAnimationEffect = false; // 用于判断删除的是哪种效果 // 合并 uiAnimationEffects 和 uiShakeEffects 并按 ListIndex 排序 List sortedEffects = new List(); sortedEffects.AddRange(myScript.uiAnimationEffects); sortedEffects.AddRange(myScript.uiShakeEffects); sortedEffects = sortedEffects.OrderBy(effect => effect.ListIndex).ToList(); // 按 ListIndex 排序 // 遍历排序后的效果列表 for (int i = 0; i < sortedEffects.Count; i++) { BaseUIEffect effect = sortedEffects[i]; // 折叠框 foldouts[i] = EditorGUILayout.Foldout(foldouts[i], $"UI动画序列 {effect.ListIndex}"); if (foldouts[i]) { EditorGUILayout.BeginVertical(GUI.skin.box); // 处理 UIAnimationEffect if (effect is UIAnimationEffect uiAnimationEffect) { uiAnimationEffect.animationType = (UIAnimationEffect.AnimationType)EditorGUILayout.EnumPopup("动画类型", uiAnimationEffect.animationType); uiAnimationEffect.duration = EditorGUILayout.FloatField("持续时间", uiAnimationEffect.duration); uiAnimationEffect.easeType = (Ease)EditorGUILayout.EnumPopup("缓动类型", uiAnimationEffect.easeType); // 如果是透明度动画(Fade),显示透明度值 if (uiAnimationEffect.animationType == UIAnimationEffect.AnimationType.Fade) { uiAnimationEffect.targetAlpha = EditorGUILayout.FloatField("目标透明度", uiAnimationEffect.targetAlpha); } else { uiAnimationEffect.targetValue = EditorGUILayout.Vector3Field("目标值", uiAnimationEffect.targetValue); } } // 处理 UIShakeEffect else if (effect is UIShakeEffect uiShakeEffect) { uiShakeEffect.shakeType = (UIShakeEffect.ShakeType)EditorGUILayout.EnumPopup("抖动类型", uiShakeEffect.shakeType); uiShakeEffect.strength = EditorGUILayout.Vector3Field("抖动强度", uiShakeEffect.strength); uiShakeEffect.vibrato = EditorGUILayout.IntField("抖动次数", uiShakeEffect.vibrato); uiShakeEffect.randomness = EditorGUILayout.FloatField("随机性", uiShakeEffect.randomness); uiShakeEffect.duration = EditorGUILayout.FloatField("持续时间", uiShakeEffect.duration); } // 允许用户更改 ListIndex effect.ListIndex = EditorGUILayout.IntField("排序索引", effect.ListIndex); if (GUILayout.Button("删除此效果")) { deleteIndex = i; isAnimationEffect = effect is UIAnimationEffect; } EditorGUILayout.EndVertical(); } // 标记动画需要更新 myScript.animationSequenceNeedsUpdate = true; } // 处理删除效果 if (deleteIndex >= 0) { BaseUIEffect effectToDelete = sortedEffects[deleteIndex]; if (isAnimationEffect) { myScript.uiAnimationEffects.Remove((UIAnimationEffect)effectToDelete); } else { myScript.uiShakeEffects.Remove((UIShakeEffect)effectToDelete); } foldouts.RemoveAt(deleteIndex); // 同时移除折叠状态 } EditorGUILayout.Space(); // 创建横排布局 EditorGUILayout.BeginHorizontal(); // 记录旧的 loopEntireSequence 值 bool previousLoopEntireSequence = myScript.loopEntireSequence; // 在同一行上显示 "是否循环整个动画序列" 和 "自定义循环类型" (自定义名称) myScript.loopEntireSequence = EditorGUILayout.Toggle(new GUIContent("循环整个动画"), myScript.loopEntireSequence); // 如果 loopEntireSequence 改变了,标记需要更新动画序列 if (myScript.loopEntireSequence != previousLoopEntireSequence) { myScript.animationSequenceNeedsUpdate = true; Debug.Log("循环整个动画选项已更改,标记动画序列需要更新"); } // 通过自定义的中文名称显示 LoopType LoopType selectedLoopType = myScript.sequenceLoopType; int selectedIndex = EditorGUILayout.Popup(new GUIContent("循环类型"), (int)selectedLoopType, loopTypeOptions); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); myScript.OnenableOpen = EditorGUILayout.Popup(new GUIContent("动画模式"), myScript.OnenableOpen,OnenableOpens); if (GUILayout.Button("复位")) { myScript.RestartAnimations(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); // 如果 LoopType 改变了,标记需要更新动画序列 if ((LoopType)selectedIndex != myScript.sequenceLoopType) { myScript.sequenceLoopType = (LoopType)selectedIndex; myScript.animationSequenceNeedsUpdate = true; Debug.Log("循环类型已更改,标记动画序列需要更新"); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); // 添加新UI动画的按钮 if (GUILayout.Button("添加基础UI动画")) { AddUIAnimationEffect(myScript); } // 添加新UI抖动效果的按钮 if (GUILayout.Button("添加UI抖动")) { AddUIShakeEffect(myScript); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); // 添加播放UI动画的按钮 if (GUILayout.Button("播放")) { myScript.PlayUIAnimations(); } // 添加暂停UI动画的按钮 if (GUILayout.Button("暂停")) { myScript.StopUIAnimations(); } EditorGUILayout.EndHorizontal(); EditorUtility.SetDirty(myScript); // 标记为已修改,确保Unity保存修改 } // 添加新的 UIAnimationEffect private void AddUIAnimationEffect(AnimationUI script) { UIAnimationEffect newEffect = new UIAnimationEffect(); script.uiAnimationEffects.Add(newEffect); foldouts.Add(true); // 默认展开新的效果 script.animationSequenceNeedsUpdate = true; // 标记序列需要更新 } // 添加新的 UIShakeEffect private void AddUIShakeEffect(AnimationUI script) { UIShakeEffect newEffect = new UIShakeEffect(); script.uiShakeEffects.Add(newEffect); foldouts.Add(true); // 默认展开新的效果 script.animationSequenceNeedsUpdate = true; // 标记序列需要更新 } // 确保折叠列表的大小与效果列表匹配 private void EnsureFoldoutListSize(AnimationUI script) { int totalEffects = script.uiAnimationEffects.Count + script.uiShakeEffects.Count; while (foldouts.Count < totalEffects) { foldouts.Add(true); // 默认展开 } } }