Unity 简易的UI框架

核心内容
UIType.cs

namespace MYTOOL.UI
{
   
    /// <summary>
    /// UI层级
    /// </summary>
    public enum UILayer
    {
   
        /// <summary>
        /// 主界面层
        /// </summary>
        MainUI = 0,
        /// <summary>
        /// 普通界面层
        /// </summary>
        NormalUI = 1,
        /// <summary>
        /// 弹出层
        /// </summary>
        PopupUI = 2,
        /// <summary>
        /// Top层 高于弹出层
        /// </summary>
        Top = 3,
        /// <summary>
        /// 加载层 加载进度或加载动画
        /// </summary>
        Loading = 4,
    }


    /// <summary>
    /// UI组
    /// </summary>
    public enum UIGroup
    {
   
        Default = 0,

        //TODO
    }
}

UIBase.cs

using UnityEngine;

namespace MYTOOL.UI
{
   
    [DisallowMultipleComponent]
    [RequireComponent(typeof(RectTransform))]
    public abstract class UIBase : MonoBehaviour
    {
   
        /// <summary>
        /// UI层级
        /// </summary>
        public virtual UILayer Layer {
    get; } = UILayer.NormalUI;
        /// <summary>
        /// UI组
        /// </summary>
        public virtual UIGroup Group {
    get; } = UIGroup.Default;

        /// <summary>
        /// 同一层单独存在
        /// </summary>
        public virtual bool IsOnly {
    get; } = false;
        /// <summary>
        /// 总显示
        /// </summary>
        public virtual bool AlwaysDisplay {
    get; } = false;

        /// <summary>
        /// UI隐藏所需时间
        /// </summary>
        public virtual float UIHideTime {
    get; } = 0;
        /// <summary>
        /// UI关闭所需时间
        /// </summary>
        public virtual float UICloseTime {
    get; } = 0;

        /// <summary>
        /// UI名称
        /// </summary>
        public string UIName {
    get; private set; }

        private bool dirty = true;

        /// <summary>
        /// 脏标记
        /// </summary>
        public void SetDirty()
        {
   
            dirty = true;
        }

        protected virtual void Update()
        {
   
            if (dirty)
            {
   
                dirty = false;
                OnDirty();
                OnRefresh();
            }

            OnUpdate();
        }

        /// <summary>
        /// 创建时执行一次
        /// </summary>
        protected abstract void OnCreate();
        /// <summary>
        /// 显示UI
        /// </summary>
        protected virtual void OnShow() {
    }
        /// <summary>
        /// 隐藏UI
        /// </summary>
        protected virtual void OnHide() {
    }
        /// <summary>
        /// 关闭UI/销毁UI
        /// </summary>
        protected virtual void OnClose() {
    }
        /// <summary>
        /// 每帧执行
        /// </summary>
        protected virtual void OnUpdate() {
    }
        /// <summary>
        /// 刷新其它
        /// </summary>
        protected virtual void OnDirty() {
    }
        /// <summary>
        /// 刷新UI
        /// </summary>
        protected virtual void OnRefresh() {
    }

        /// <summary>
        /// 进入效果(显示)
        /// </summary>
        protected virtual void OnEnterEffect() {
    }
        /// <summary>
        /// 隐藏效果
        /// </summary>
        protected virtual void OnHideEffect() => OnExitEffect();
        /// <summary>
        /// 退出效果(隐藏/关闭)
        /// </summary>
        protected virtual void OnExitEffect() {
    }


        #region >> 内部方法

        protected RectTransform root;
        internal void InitUI(string uiName)
        {
   
            root = GetComponent<RectTransform>();
            root.localPosition = Vector3.zero;
            root.localScale = Vector3.one;
            root.anchorMin = Vector2.zero;
            root.anchorMax = Vector2.one;
            root.offsetMin = Vector2.zero;
            root.offsetMax = Vector2.zero;

            UIName = uiName;
            OnCreate();
        }

        internal void ShowUI()
        {
   
            gameObject.SetActive(true);
            transform.SetAsLastSibling();

            OnEnterEffect();
            OnShow();
        }

        internal void HideUI()
        {
   
            if (AlwaysDisplay)
            {
   
                Debug.LogWarning("Can't hide");
                return;
            }

            if (UIHideTime > 0)
            {
   
                OnHideEffect();
                OnHide();
                this.Seconds(UIHideTime, () => gameObject.SetActive(false));
            }
            else
            {
   
                OnHide();
                gameObject.SetActive(false);
            }
        }

        internal void CloseUI()
        {
   
            if (UICloseTime > 0)
            {
   
                OnExitEffect();
            }
            OnClose();
            Destroy(gameObject, UICloseTime);
        }

        internal void RefreshUI()
        {
   
            SetDirty();
        }

        #endregion
    }
}

UIManager.cs

using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;

namespace MYTOOL.UI
{
   
    /// <summary>
    /// UI管理类
    /// </summary>
    public partial class UIManager : MonoBehaviour
    {
   
        /// <summary>
        /// UI预设加载函数
        /// </summary>
        public Func<string, GameObject> ResLoaderFunc = uiPath => ResLoader.Ins.Load<GameObject>(uiPath, true);
        /// <summary>
        /// UI预设基础路径格式
        /// </summary>
        private const string UI_PREFAB_PATH_FORMAT = "UI/{0}";
        /// <summary>
        /// UI预设模块路径格式
        /// </summary>
        private const string UI_PREFAB_MODULE_PATH_FORMAT = "UI/{0}/{1}";


        #region >> 私有变量

        private Transform MainParent;
        private Transform NormalParent;
        private Transform PopParent;
        private Transform TopParent;
        private Transform LoadingParent;

        private readonly Dictionary<string, UIBase> UIBaseMap = new Dictionary<string, UIBase>();
        private UIBase CurrentMainUI;

        private readonly List<UIBase> NormalUIList = new List<UIBase>(16);
        private readonly List<UIBase> PopUIList = new List<UIBase>(16);

        #endregion


        private static UIManager _instace;

        public static UIManager Ins => Instance;

        public static UIManager Instance
        {
   
            get
            {
   
                if (_instace == null)
                {
   
                    var canvasPrefab = Resources.Load<GameObject>("MainCanvas");
                    var canvsGo = Instantiate(canvasPrefab);
                    canvsGo.name = "MainCanvas";
                    if (!canvsGo.TryGetComponent<UIManager>(out _instace))
                    {
   
                        _instace = canvsGo.AddComponent<UIManager>();
                    }
                    _instace.OnInit();

                    if (DebugMode) LogInfo($"UIManager initalize !");

                    DontDestroyOnLoad(_instace);
                }

                return _instace;
            }
        }

        private void OnInit()
        {
   
            MainParent = transform.Find("MainUI");
            NormalParent = transform.Find("NormalUI");
            PopParent = transform.Find("PopupUI");
            TopParent = transform.Find("Top");
            LoadingParent = transform.Find("Loading");
        }

        private void OnDestroy()
        {
   
            UIBaseMap.Clear();
            NormalUIList.Clear();
            PopUIList.Clear();
        }

        /// <summary>
        /// 获取UI相机
        /// </summary>
        /// <returns></returns>
        public Camera GetUICamera()
        {
   
            Canvas canvas = GetComponent<Canvas>();
            if (canvas.worldCamera)
                return canvas.worldCamera;

            return Camera.main;
        }

        public Transform GetUIParent(UILayer layer)
        {
   
            return layer switch
            {
   
                UILayer.MainUI => MainParent,
                UILayer.NormalUI => NormalParent,
                UILayer.PopupUI => PopParent,
                UILayer.Top => TopParent,
                UILayer.Loading => LoadingParent,
                _ => transform,
            };
        }


        #region >> 显示UI

        /// <summary>
        /// 显示UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T ShowUI<T>() where T : UIBase
        {
   
            return InternalShowUI<T>(typeof(T).Name, string.Empty);
        }

        /// <summary>
        /// 显示UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uiName">UI名称/预制体名称</param>
        /// <returns></returns>
        public T ShowUI<T>(string uiName) where T : UIBase
        {
   
            return InternalShowUI<T>(uiName, string.Empty);
        }

        /// <summary>
        /// 显示模块UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="modulePath">模块路径</param>
        /// <returns></returns>
        public T ShowModuleUI<T>(string modulePath) where T : UIBase
        {
   
            return InternalShowUI<T>(typeof(T).Name, modulePath);
        }

        /// <summary>
        /// 显示模块UI
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="uiName">UI名称/预制体名称</param>
        /// <param name="modulePath">模块路径</param>
        /// <returns></returns>
        public T ShowModuleUI<T>(string uiName, string modulePath) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值