Unity 简单UI框架(二)

框架整体介绍:

1、UIManager中加载所有UI,存到列表中,使用时实例化到场景,根据类型分层

2、各面板继承BasePanel,自己进行生命周期管理

细节整理:

1、面板属性定义

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:TypeDefine
* 创建日期:2019-12-03 11:17:00
* 作者名称:末零
* 功能描述:定义UI面板属性的枚举
******************************************************************************/

namespace LastZero
{
    /// <summary>
    /// 面板类型
    /// </summary>
    public enum PanelType
    {
        Normal,  //普通UI
        Fixed,   //固定窗口(例:Top)
        PopUp    //弹出
    }

    /// <summary>
    /// 显示类型
    /// </summary>
    public enum PanelShowType
    {
        DoNothing,      //无操作
        HideOther,      //关闭其他界面
        SelfControl,    //不受HideOther影响
        DoBack          //返回功能
    }

    /// <summary>
    /// 遮罩类型
    /// </summary>
    public enum PanelMaskType
    {
        None,   //显示该界面不包含碰撞背景
        NoBg,   //碰撞透明背景
        WithBg, //碰撞非透明背景
    }
}

2、面板属性设置

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:UIType
* 创建日期:2019-12-03 11:25:49
* 作者名称:末零
* 功能描述:面板属性
******************************************************************************/

using UnityEngine;

namespace LastZero
{
    /// <summary>
    /// 面板属性
    /// </summary>
    public class UIType : MonoBehaviour
	{
        /// <summary>
        /// UI类型
        /// </summary>
        public PanelType panelType = PanelType.Normal;
        /// <summary>
        /// UI显示类型
        /// </summary>
        public PanelShowType showType = PanelShowType.DoNothing;
        /// <summary>
        /// UI遮罩类型
        /// </summary>
        public PanelMaskType maskType = PanelMaskType.None;

        /// <summary>
        /// 设置
        /// </summary>
        /// <param name="pt">UI类型</param>
        /// <param name="pst">UI显示类型</param>
        /// <param name="pmt">UI遮罩类型</param>
        public void SetType(PanelType pt, PanelShowType pst, PanelMaskType pmt)
        {
            panelType = pt;
            showType = pst;
            maskType = pmt;
        }
    }
}

 3、系统定义(路径定义为例)

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:PathDefine
* 创建日期:2019-12-03 11:30:02
* 作者名称:末零
* 功能描述:路径常量定义
******************************************************************************/

namespace LastZero
{
    /// <summary>
    /// 路径常量定义
    /// </summary>
    public class PathDefine
	{
        public const string canvasPath = "UIPrefabs/Canvas/MainCanvas";//Canvas路径
        public const string panelPath = "UIPrefabs/Panels";//面板预制体路径
        public const string maskPanelPath = "PopUp/MaskPanel";//遮罩面板Hierarchy路径
    }
}

4、记录器

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:Recorder
* 创建日期:2019-12-05 16:47:01
* 作者名称:末零
* 功能描述:记录器
******************************************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace LastZero
{
    /// <summary>
    /// 记录器
    /// </summary>
    public class Recorder
	{
		
	}
}

下面重点说下基类和UI管理类:

5、BasePanel

首先自己定义面板属性,

生命周期:

(1)Init,相当于Awake,在面板被实例化的时候执行一次

(2)OnShow、OnHide,相当于OnEnable和OnDisable

没有做其它生命周期

接下来呢,面板自身定义Show和Hide方法,此处采用Scale控制

对于Show,特殊说明一下,因为第一次使用面板时,需要实例化,所以此处需有判断,若未实例化,则实例化,删除列表中的面板,加入实例化出的新面板,显示时通过属性判断,设置层,设置类型。对于Hide呢,主要需要判断是否需要关闭Mask。

代码如下:

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:BasePanel
* 创建日期:2019-12-03 11:14:13
* 作者名称:末零
* 功能描述:面板基类
******************************************************************************/

using UnityEngine;
using UnityEngine.UI;

namespace LastZero
{
    /// <summary>
    /// 面板基类
    /// </summary>
    public class BasePanel : MonoBehaviour
	{
        #region 面板属性
        /// <summary>
        /// 面板属性
        /// </summary>
        private UIType uiType = new UIType();

        /// <summary>
        /// 属性(程序集)_当前Panel类型
        /// </summary>
        internal UIType CurrentUIType
        {
            set { uiType = value; }
            get { return uiType; }
        }
        #endregion

        #region 面板显示

        /// <summary>
        /// 面板
        /// </summary>
        private BasePanel panel;

        /// <summary>
        /// 显示面板
        /// </summary>
        public BasePanel Show()
        {
            panel = this;
            if (transform.parent == null)
            {
                panel = InstantiatePanel();
            }
            else
            {
                SetShowType(this);
            }
            transform.localScale = Vector3.one;

            //如果是弹出面板 设置遮罩
            if (panel.uiType.panelType == PanelType.PopUp)
                SetMask();

            OnShow();
            return panel;
        }

        /// <summary>
        /// 实例化面板
        /// </summary>
        public BasePanel InstantiatePanel()
        {
            BasePanel newPanel = Instantiate(this);
            newPanel.Init();
            UIManager.GetInstance().Panels.Remove(this);
            UIManager.GetInstance().Panels.Add(newPanel);
            newPanel.transform.SetParent(UIManager.GetInstance().GetCanvas().Find(newPanel.CurrentUIType.panelType.ToString()), false);
            newPanel.gameObject.SetActive(true);
            SetShowType(newPanel);
            return newPanel;
        }

        /// <summary>
        /// 初始化(相当于Awake)
        /// </summary>
        protected virtual void Init()
        {
            SetPanelType();
        }

        /// <summary>
        /// 设置面板类型
        /// </summary>
        protected virtual void SetPanelType(){ }

        /// <summary>
        /// 设置显示类型
        /// </summary>
        /// <param name="panel"></param>
        private void SetShowType(BasePanel panel)
        {
            if (panel.CurrentUIType.showType == PanelShowType.HideOther)
            {
                for (int i = 0; i < UIManager.GetInstance().Panels.Count; i++)
                {
                    if (UIManager.GetInstance().Panels[i].transform.parent != null && UIManager.GetInstance().Panels[i].CurrentUIType.showType != PanelShowType.SelfControl)
                        UIManager.GetInstance().Panels[i].Hide();
                }
            }
            else if (panel.CurrentUIType.showType == PanelShowType.DoBack)
            {
                UIManager.GetInstance().panelsDoBack.Push(panel);
            }
        }

        /// <summary>
        /// 设置遮罩
        /// </summary>
        private void SetMask()
        {
            Image mask = UIManager.GetInstance().GetCanvas().Find(PathDefine.maskPanelPath).GetComponent<Image>();

            switch (panel.uiType.maskType)
            {
                case PanelMaskType.None:
                    mask.gameObject.SetActive(false);
                    break;
                case PanelMaskType.NoBg:
                    mask.gameObject.SetActive(true);
                    mask.color = new Color(1, 1, 1, 0);
                    break;
                case PanelMaskType.WithBg:
                    mask.gameObject.SetActive(true);
                    mask.color = new Color(1, 1, 1, 1);
                    break;
            }
        }

        /// <summary>
        /// 显示时要执行的方法
        /// </summary>
        protected virtual void OnShow() { }
        #endregion

        #region 面板隐藏
        /// <summary>
        /// 隐藏面板
        /// </summary>
        public void Hide()
        {
            transform.localScale = Vector3.zero;

            if (uiType.panelType == PanelType.PopUp)
                UIManager.GetInstance().GetCanvas().Find(PathDefine.maskPanelPath).gameObject.SetActive(false);

            OnHide();
        }

        /// <summary>
        /// 隐藏时要执行的方法
        /// </summary>
        protected virtual void OnHide() { }
        #endregion

        #region 获取面板
        /// <summary>
        /// 获取组件
        /// </summary>
        /// <typeparam name="T">组件</typeparam>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public T GetMyComponent<T>(string path)
        {
            return transform.Find(path).GetComponent<T>();
        }
        #endregion
    }
}

6、UIManager

首先,加载Canvas,加载所有面板存储,在管理类中进行界面显隐(此处做特殊说明,面板通过类来存储,显示隐藏时由泛型查找),另外界面的回退也再次通过栈来控制。

/*******************************************************************************
* 版本声明:v1.0.0
* 类 名 称:UIManger
* 创建日期:2019-12-03 13:25:17
* 作者名称:末零
* 功能描述:UI管理类
******************************************************************************/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace LastZero
{
    /// <summary>
    /// UI管理类
    /// </summary>
    public class UIManager
	{
        /// <summary>
        /// 构造
        /// </summary>
        private UIManager()
        {
            InitRootCanvasLoading();
            AddAllPanel(PathDefine.panelPath);
        }

        #region 单例
        private static UIManager _instance = null;

        /// <summary>
        /// 单例
        /// </summary>
        /// <returns></returns>
        public static UIManager GetInstance()
        {
            if (_instance == null)
            {
                _instance = new UIManager();
            }
            return _instance;
        }
        #endregion

        #region Canvas、Panels
        /// <summary>
        /// Canvas
        /// </summary>
        private Transform canvas = null;

        /// <summary>
        /// 初始化加载Canvas预设
        /// </summary>
        private void InitRootCanvasLoading()
        {
            canvas = Object.Instantiate(Resources.Load<Transform>(PathDefine.canvasPath));
        }

        /// <summary>
        /// 获取Canvas
        /// </summary>
        /// <returns>canvas</returns>
        public Transform GetCanvas()
        {
            if (canvas == null)
                canvas = Object.FindObjectOfType<MainCanvas>().transform;

            return canvas;
        }

        /// <summary>
        /// 面板列表
        /// </summary>
        //private List<BasePanel> panelsNotInstantiate = new List<BasePanel>();
        private List<BasePanel> panels = new List<BasePanel>();

        /// <summary>
        /// 面板访问器
        /// </summary>
        public List<BasePanel> Panels
        {
            get { return panels; }
        }

        /// <summary>
        /// 添加面板到列表
        /// </summary>
        /// <param name="panel">面板</param>
        public void AddAllPanel(string path)
        {
            panels.AddRange(Resources.LoadAll<BasePanel>(path));
        }

        /// <summary>
        /// 有返回功能的面板
        /// </summary>
        public Stack<BasePanel> panelsDoBack = new Stack<BasePanel>();

        /// <summary>
        /// 返回上一个页面
        /// </summary>
        public void DoBack()
        {
            panelsDoBack.Pop().Hide();
            panelsDoBack.Peek().Show();
        }
        #endregion

        #region 面板显隐
        /// <summary>
        /// 显示面板
        /// </summary>
        /// <typeparam name="T">面板</typeparam>
        /// <returns>PanelBase</returns>
        public T ShowPanel<T>() where T : BasePanel
        {
            BasePanel panel = panels.Find(p => p is T);
            return ShowPanel(panel) as T;
        }

        /// <summary>
        /// 显示面板
        /// </summary>
        /// <param name="panel">面板</param>
        /// <returns>PanelBase</returns>
        private BasePanel ShowPanel(BasePanel panel)
        {
            if (panel == null)
                return null;

            return panel.Show();
        }

        /// <summary>
        /// 隐藏面板
        /// </summary>
        /// <typeparam name="T">面板</typeparam>
        /// <returns>PanelBase</returns>
        public T HidePanel<T>() where T : BasePanel
        {
            BasePanel panel = panels.Find(p => p is T);
            HidePanel(panel);
            return panel as T;
        }

        /// <summary>
        /// 隐藏面板
        /// </summary>
        /// <param name="panel">面板</param>
        /// <returns>PanelBase</returns>
        private static void HidePanel(BasePanel panel)
        {
            if (panel == null)
                return;

            panel.Hide();
        }

        /// <summary>
        /// 获取面板
        /// </summary>
        /// <typeparam name="T">面板</typeparam>
        /// <returns>PanelBase</returns>
        public T GetPanel<T>() where T : BasePanel
        {
            BasePanel panel = panels.Find(p => p is T);

            return panel as T;
        }
        #endregion
    }
}

至此,框架基本就搭建完了,但是 ,涉及到UI界面与3维物体的交互,不打算采用消息传递机制,后面会继续研究,也会有其他方面的扩展。

返回目录

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值