简单的UIPanel框架

在unity中使用UGUI,想要panel依次显示,退出,更好的管理各种UI界面,使用栈的方式管理所有的想要加载的UI界面。

1、首先新建要加载的UIPanel枚举类型文件名为UIPanelType

public enum UIPanelType
{
    Start,
    Register,
    Message,
    Progress,
}
2、新建解析panel类型类UIPanelInfo

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class UIPanelInfo : ISerializationCallbackReceiver
{
    [NonSerialized]
    public UIPanelType panelType;//Panel类型

    public string panelTypeString;//Panel类型(string)
    public string path;//UIPrefab路径
    public void OnAfterDeserialize()
    {
        //将string类型转换成枚举类型的
        UIPanelType type = (UIPanelType) System.Enum.Parse(typeof(UIPanelType), panelTypeString);
        panelType = type;
    }

    public void OnBeforeSerialize()
    {

    }
}
3、新建存储Panel路径和类型的Json文件UIPanelType.json

{
"infoList": 
[
	{"panelTypeString": "Start",
		"path": "UIPanel/StartPanel"},

	{"panelTypeString": "Register",
		"path": "UIPanel/RegisterPanel"}, 

	{"panelTypeString": "Message",
		"path": "UIPanel/MessagePanel"},

	{"panelTypeString": "Progress",
		"path": "UIPanel/ProgressPanel"}
]
}

4、新建用来继承的Panel类,用来显示和隐藏panel的类型。BasePanel

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

public class BasePanel : MonoBehaviour
{
    /// <summary>
    /// 界面被点击,显示界面
    /// </summary>
    public virtual void OnEnter()
    {
        
    }

    /// <summary>
    /// 界面被暂停,不被点击
    /// </summary>
    public virtual void OnPause()
    {
        
    }

    /// <summary>
    /// 界面继续
    /// </summary>
    public virtual void OnResume()
    {
        
    }

    /// <summary>
    /// 界面不显示,界面退出
    /// </summary>
    public virtual void OnExit()
    {
        
    }
//用来新建panel,加载其他界面
    //public virtual void OnPushPanel(string panelTypeString,string message=null)
    //{
    //    UIPanelType uiPanelType = (UIPanelType) System.Enum.Parse(typeof(UIPanelType), panelTypeString);
    //    UIManager.Instance.PushPanel(uiPanelType,message);
       
    //}

}

5、新建用来解析josn文件,和管理Panel路径和prefabs以及panel显示和隐藏和方法的类UIManager

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

public class UIManager
{
    private static UIManager _instance;

    public static UIManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new UIManager();
            }
            return _instance;
        }
    }
    private Transform canvasTransform;

    public Transform CanvasTransform
    {
        get
        {
            if (canvasTransform == null)
            {
                canvasTransform = GameObject.Find("Canvas").transform;
            }
            return canvasTransform;
        }
    }

    private Dictionary<UIPanelType, string> panelPathDict;//存储所有面板prefab的路径
    private Dictionary<UIPanelType, BasePanel> panelDict;//保存所有实例化面板的游戏物体身上的BasePanel组件
    private Stack<BasePanel> stackPanel;

    private UIManager()
    {
        ParseUIPanelTypeJson();
    }
    /// <summary>
    /// 把某个页面入栈,把某个页面显示在界面上
    /// </summary>
    /// <param name="panelType"></param>
    public void PushPanel(UIPanelType panelType, string message = "")
    {
        if (stackPanel == null)
        {
            stackPanel = new Stack<BasePanel>();
        }
        //判断一下是否已经有页面了,如果有了就要把栈顶的panel暂停使用
        if (stackPanel.Count > 0)
        {
            BasePanel topPanel = stackPanel.Peek();
            topPanel.OnPause();

           // Debug.Log("栈顶"+topPanel);
        }
        BasePanel panel = GetPanel(panelType);
        panel.OnEnter();
       // Debug.Log("入栈后:"+panel);
        stackPanel.Push(panel);
        
    }
    /// <summary>
    /// 出栈,把某个页面从界面上移除
    /// </summary>
    public void PopPanel()
    {
        if (stackPanel == null)
        {
            stackPanel = new Stack<BasePanel>();
        }
        if (stackPanel.Count <= 0) return;
        BasePanel topPanel1 = stackPanel.Pop();
        topPanel1.OnExit();
        if (stackPanel.Count <= 0) return;
        BasePanel topPanel2 = stackPanel.Peek();
        topPanel2.OnResume();
    }
    public BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict == null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
        }

        BasePanel panel = panelDict.TryGet(panelType);

        //如果panel为空,说明该panel没有被实例化,应该实例化
        if (panel == null)
        {
            string path = panelPathDict.TryGet(panelType);
            GameObject instanPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
            instanPanel.transform.SetParent(CanvasTransform, false);
            panelDict.Add(panelType, instanPanel.GetComponent<BasePanel>());
            return instanPanel.GetComponent<BasePanel>();
        }
        else
        {
            return panel;
        }
    }

    [Serializable]
    class UIPanelTypeJson
    {
        public List<UIPanelInfo> infoList;
    }

    //读取json数据,获取所有面板prefab的路径
    private void ParseUIPanelTypeJson()
    {
        panelPathDict = new Dictionary<UIPanelType, string>();
        TextAsset textAsset = Resources.Load<TextAsset>("UIPanel/UIPanelType");
        UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(textAsset.text);
        foreach (UIPanelInfo info in jsonObject.infoList)
        {
            panelPathDict.Add(info.panelType, info.path);
        }
    }
}

6、最后根据需要新建要管理的Panel类,继承BasePanel.并重现父类的方法,再实现父类方法并在方法中管理该panel显示或者隐藏。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值