在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显示或者隐藏。