using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; public enum E_UILayer { /// /// 最底层 /// Bottom, /// /// 中层 /// Middle, /// /// 高层 /// Top, /// /// 系统层 最高层 /// System, } public class UIManager { private static UIManager instance = new UIManager(); public static UIManager Instance => instance; //用于存储显示着的面板的 没显示一个面板 就会存入这个字典 //隐藏面板时 直接获取字典中的对应面板 进行隐藏 private Dictionary panelDic = new Dictionary(); //场景中 Canvas对象 用于设置为面板的父对象 private Transform canvasTrans; //层级父对象 private Transform bottomLayer; private Transform middleLayer; private Transform topLayer; private Transform systemLayer; private UIManager() { //得到场景中的Canvas对象 GameObject canvas = GameObject.Instantiate(Resources.Load("UI/Canvas")); canvasTrans = canvas.transform; //通过过场景不移除该对象 保证这个游戏过程中 只有一个 canvas对象 GameObject.DontDestroyOnLoad(canvas); //找到层级父对象 bottomLayer = canvas.transform.Find("Bottom"); middleLayer = canvas.transform.Find("Middle"); topLayer = canvas.transform.Find("Top"); systemLayer = canvas.transform.Find("System"); } /// /// 获取对应层级的父对象 /// /// 层级枚举值 /// public Transform GetLayerFather(E_UILayer layer) { switch (layer) { case E_UILayer.Bottom: return bottomLayer; case E_UILayer.Middle: return middleLayer; case E_UILayer.Top: return topLayer; case E_UILayer.System: return systemLayer; default: return null; } } //显示面板 public T ShowPanel(E_UILayer layer) where T:BasePanel { //我们只需要保证 泛型T的类型 和面板预设体名字 一样 定一个这样的规则 就可以非常方便的让我们使用了 string panelName = typeof(T).Name; //判断 字典中 是否已经显示了这个面板 if (panelDic.ContainsKey(panelName)) { return panelDic[panelName] as T; } //显示面板 根据面板名字 动态的创建预设体 设置父对象 GameObject panelObj = GameObject.Instantiate(Resources.Load("UI/" + panelName)); //层级的处理 Transform father = GetLayerFather(layer); //避免没有按指定规则传递层级参数 避免为空 if (father == null) father = middleLayer; //把这个对象 放到场景中的Canvas下面 panelObj.transform.SetParent(father, false); //执行面板上 显示逻辑 并且应该把它保存起来 T panel = panelObj.GetComponent(); //把这个面板脚本 存储到字典中 方便之后的 获取 和 隐藏 panelDic.Add(panelName, panel); return panel; } /// /// 隐藏面板 /// /// 面板类名 /// 是否淡出完毕过后才删除面板 默认是true public void HidePanel() where T : BasePanel { //根据泛型的得到名字 string panelName = typeof(T).Name; //判断当前显示的面板 有没有你想隐藏的 if (panelDic.ContainsKey(panelName)) { //删除对象 GameObject.Destroy(panelDic[panelName].gameObject); //删除字典里面存储的面板脚本 panelDic.Remove(panelName); } } //得到面板 public T GetPanel() where T : BasePanel { string panelName = typeof(T).Name; if (panelDic.ContainsKey(panelName)) { return panelDic[panelName] as T; } //如果没有对应显示的 就为空 return null; } }