源码下载地址:https://download.csdn.net/download/f402455894/21356757?spm=1001.2014.3001.5501
文件结构
PanelInfo
using System;
using System.Collections.Generic;
[Serializable]
public class UIPanelInfo
{
public string panelTypeString;
public string path;
}
[Serializable]
public class UIPanelTypeJson
{
public List<UIPanelInfo> infoList;
}
UIPanelType和Json根据项目情况编写(切记:panelTypeString 和UIPanelType中的字符串还有相对应的UI预制体的名称要一致)
public class UIPanelType
{
public const string Backpacker = "Panel_Backpacker";
public const string HomePage = "Panel_HomePage";
public const string Shopping = "Panel_Shopping";
public const string System = "Panel_System";
public const string Task = "Panel_Task";
}
{
"infoList":
[
{
"panelTypeString": "Panel_Backpacker",
"path": "UI/Panel_Backpacker"
},
{
"panelTypeString": "Panel_HomePage",
"path": "UI/Panel_HomePage"
},
{
"panelTypeString": "Panel_Shopping",
"path": "UI/Panel_Shopping"
},
{
"panelTypeString": "Panel_System",
"path": "UI/Panel_System"
},
{
"panelTypeString": "Panel_Task",
"path": "UI/Panel_Task"
}
]
}
Manager
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 UIManager()
{
ParseUIPanelTypeJson();
GetScenesPanel();
}
private Dictionary<string, string> panelPathDict;
private Dictionary<string, BasePanel> panelDict;
private Stack<BasePanel> panelStack;
private Transform canvesTransform;
private BasePanel[] basePanels;
private Transform CanvesTransform
{
get
{
if (canvesTransform == null)
{
canvesTransform = GameObject.Find("Canvas").transform;
}
return canvesTransform;
}
}
/// <summary>
/// 显示UI
/// </summary>
/// <param name="panelType">UI名字</param>
public void PushPanel(string panelType)
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
if (panelStack.Count > 0)
{
//取当前栈顶元素
BasePanel topPanel = panelStack.Peek();
topPanel.OnPause();
}
BasePanel basePanel = GetPanel(panelType);
//保证加载出来的东西都在UI画布的最上层
basePanel.transform.SetSiblingIndex(CanvesTransform.childCount-1);
basePanel.OnEnter();
//将要显示的UI推入栈里
panelStack.Push(basePanel);
}
/// <summary>
/// 隐藏UI
/// </summary>
public void PopPanel()
{
if (panelStack == null)
panelStack = new Stack<BasePanel>();
if (panelStack.Count <= 0)
{
return;
}
//将要隐藏的UI弹出栈
BasePanel basePanel_1 = panelStack.Pop();
basePanel_1.OnExit();
if (panelStack.Count <= 0)
{
return;
}
//如果栈里还有元素,获取到当前的UI,让这个UI变成活跃的状态
BasePanel basePanel_2 = panelStack.Peek();
basePanel_2.OnResume();
}
/// <summary>
/// 获得UI
/// </summary>
/// <param name="panelType">UI的名字</param>
/// <returns></returns>
private BasePanel GetPanel(string panelType)
{
if (panelDict == null)
{
panelDict = new Dictionary<string, BasePanel>();
}
//取得字典中的value(dictionary扩展方法)
BasePanel panel = panelDict.TryGet(panelType);
//BasePanel panel;
//panelDict.TryGetValue(panelType, out panel);
if (panel == null)
{
string path = panelPathDict.TryGet(panelType);
GameObject instPanel = GameObject.Instantiate(Resources.Load(path), CanvesTransform, false) as GameObject;
instPanel.name = panelType;
if (panelDict.ContainsKey(panelType))
Debug.LogError("Key值已经存在");
else
panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());
return instPanel.GetComponent<BasePanel>();
}
else
{
return panel;
}
}
/// <summary>
/// 解析Json,将UI的名称和路径存入字典中。
/// </summary>
private void ParseUIPanelTypeJson()
{
panelPathDict = new Dictionary<string, string>();
TextAsset ta = Resources.Load<TextAsset>("UIJson/UIPanelType");
UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);
foreach (UIPanelInfo info in jsonObject.infoList)
{
if (panelPathDict.ContainsKey(info.panelTypeString))
Debug.LogError("Key值重复");
else
panelPathDict.Add(info.panelTypeString, info.path);
}
basePanels = CanvesTransform.GetComponentsInChildren<BasePanel>();
}
/// <summary>
/// 获取到场景中挂载的UI,防止再次从Resources里加载
/// </summary>
private void GetScenesPanel()
{
if (panelDict == null)
{
panelDict = new Dictionary<string, BasePanel>();
}
foreach (BasePanel panel in basePanels)
{
if (panelDict.ContainsKey(panel.name))
Debug.LogError("Key值已经存在");
else
panelDict.Add(panel.name, panel);
}
}
}
将这个脚本挂场景上,场景里建一个Canves
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameRoot : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
UIManager.Instance.PushPanel(UIPanelType.HomePage);
}
}
Base
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CanvasGroup))]
public class BasePanel : MonoBehaviour
{
public virtual void Start()
{
}
/// <summary>
/// UI每次显示
/// </summary>
public virtual void OnEnter()
{
}
/// <summary>
/// UI进入失活状态
/// </summary>
public virtual void OnPause()
{
}
/// <summary>
/// UI被激活
/// </summary>
public virtual void OnResume()
{
}
/// <summary>
/// UI关闭
/// </summary>
public virtual void OnExit()
{
}
}
Extension
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class DictionaryExtension
{
/// <summary>
/// Dictionary扩展方法,获取对应Key的Value值
/// </summary>
/// <typeparam name="Tkey"></typeparam>
/// <typeparam name="Tvalue"></typeparam>
/// <param name="dict"></param>
/// <param name="tkey"></param>
/// <returns></returns>
public static Tvalue TryGet<Tkey,Tvalue>(this Dictionary<Tkey, Tvalue> dict,Tkey tkey)
{
Tvalue tvalue;
dict.TryGetValue(tkey, out tvalue);
return tvalue;
}
}
PanelUI 实例
根据具体项目情况编写
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Panel_System : BasePanel
{
public CanvasGroup canvasGroup;
public override void OnEnter()
{
canvasGroup.alpha = 1;
canvasGroup.blocksRaycasts = true;
}
public override void OnExit()
{
canvasGroup.alpha = 0;
canvasGroup.blocksRaycasts = false;
}
public void OnClosePanel()
{
UIManager.Instance.PopPanel();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Panel_HomePage : BasePanel
{
public CanvasGroup canvasGroup;
public override void OnPause()
{
canvasGroup.blocksRaycasts = false;
}
public override void OnResume()
{
canvasGroup.blocksRaycasts = true;
}
public void OnPushPanel(string str)
{
UIManager.Instance.PushPanel(str);
}
}