using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; // DOTween 插件引用 using Cysharp.Threading.Tasks; using System; public enum UILayer { Static, // 静态UI 适合做 战斗 主界面 Bottom, // 主界面 Mid, // 功能窗口 System, // 网络弹窗/其他重要弹窗 Loading, // 加载界面 } public enum UIAnimationType { None, // 无动画 FadeInOut, // 淡入淡出 ScaleInOut, // 缩放 SlideFromTop, // 从顶部滑入 SlideFromBottom, // 从底部滑入 SlideFromLeft, // 从左侧滑入 SlideFromRight, // 从右侧滑入 ScaleOverInOut,// 缩放根据曲线 } [RequireComponent(typeof(Canvas))] [RequireComponent(typeof(CanvasGroup))] [RequireComponent(typeof(CanvasScaler))] public class UIBase : MonoBehaviour { #region 属性和变量 // UI基本属性 [SerializeField] public UILayer uiLayer = UILayer.Mid; [SerializeField][HideInInspector] public string uiName; [SerializeField] public bool isMainUI = false; [SerializeField] public bool supportParentChildRelation = true; // 新增:是否支持父子关系 // 持久化相关 [SerializeField] public bool isPersistent = false; [SerializeField][HideInInspector] public int maxIdleRounds = 20; // 动画相关 [SerializeField] public UIAnimationType openAnimationType = UIAnimationType.None; [SerializeField] public UIAnimationType closeAnimationType = UIAnimationType.None; [SerializeField] protected RectTransform _rectTransform; //界面默认添加根节点用于表现界面开启关闭动画,或者设置适配用 [SerializeField]/*[HideInInspector]*/ public float animeDuration = 0.2f; [SerializeField]public TweenCurve scaleOverInOutCurve; [SerializeField][HideInInspector] public Ease animationEase = Ease.OutQuad; // 确保使用 DG.Tweening.Ease // 运行时状态 [HideInInspector] public int lastUsedRound = 0; [HideInInspector] public UIBase parentUI; // 子UI管理 [HideInInspector] public List childrenUI = new List(); // 打开遮罩 [SerializeField] public bool openMask = false; // 点击空白区域关闭界面 [SerializeField] public bool clickEmptySpaceClose = false; private GameObject screenMask = null; private Button btnClickEmptyClose; // 跟OneLevelWin联动 实际上是需要继承自OneLevelWin才能生效的值 使用需要注意 int m_FunctionOrder = 0; public int functionOrder { get { return m_FunctionOrder; } set { m_FunctionOrder = value; } } // 内部状态 protected bool isActive = false; protected bool isAnimating = false; protected bool isClosing = false; // 新增:标记是否正在关闭 // 组件引用 protected Canvas canvas; protected CanvasGroup canvasGroup; // 动画相关 protected Vector3 originalPosition; protected Sequence currentAnimation; private CanvasScaler canvasScaler; #endregion #region Unity生命周期 protected virtual void Awake() { // 防止有人不写base.InitComponent引发错误 所以拆分 InitComponentInternal(); // 在Awake中进行基本初始化 InitComponent(); // 保存原始值用于动画 if (_rectTransform != null) { originalPosition = _rectTransform.anchoredPosition; } ApplySettings(); if (openMask) { screenMask = GameObject.Instantiate(Resources.Load("Prefabs/ScreenMask"), transform); screenMask.transform.localScale = Vector3.one; screenMask.transform.localPosition = Vector3.zero; screenMask.transform.SetAsFirstSibling(); } } protected virtual void Start() { // 子类可以重写此方法进行额外初始化 } protected async UniTask ApplySettings() { if (clickEmptySpaceClose) { //延迟创建会导致层级在ScreenMask之上 GameObject goBtnESC = GameObject.Instantiate(Resources.Load("Prefabs/ClickEmptyCloseMask"), transform); btnClickEmptyClose = goBtnESC.GetComponent