1、代码
public class UIManager
{private static UIManager instance = new UIManager();public static UIManager Instance => instance;//存储显示着的面板脚本(不是面板Gameobject),每显示一个面板就存入字典//隐藏的时候获取字典中对应面板 进行隐藏private Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();//得到Canvas用于设置为面板父对象private Transform canvasTrans;private UIManager(){//将Canvas作为预设体,UI管理器启动时创建CanvasGameObject canvas = GameObject.Instantiate(Resources.Load<GameObject>("UI/Canvas"));//得到创建的canvascanvasTrans = canvas.transform;//不移除Canvas,保证整个游戏中只有一个GameObject.DontDestroyOnLoad(canvas);}//显示面板public T ShowPanel<T>() where T:BasePanel{//保证泛型T的类型和预设体名字一样(规则)string panelName = typeof(T).Name;//判断字典中是否已经有这个面板if (panelDic.ContainsKey(panelName)){return panelDic[panelName] as T;}//如果字典中没有//根据面板名字动态创建预设体 设置父对象GameObject panelObj = GameObject.Instantiate(Resources.Load<GameObject>("UI/" + panelName));//把这个对象放到场景Canvas下面panelObj.transform.SetParent(canvasTrans,false);//T panel = panelObj.GetComponent<T>();//把这个面板脚本 存储到字典中panelDic.Add(panelName, panel);panel.ShowMe();return panel;}/// <summary>/// 隐藏面板/// </summary>/// <typeparam name="T">面板类型</typeparam>public void HidePanel<T>() where T : BasePanel{//根据泛型得名字string panelName = typeof(T).Name;//判断当前显示的面板有没有传入的面板if (panelDic.ContainsKey(panelName)){//面板淡出完毕后删除panelDic[panelName].HideMe(()=> {GameObject.Destroy(panelDic[panelName].gameObject);//删除字典里面存储的面板脚本panelDic.Remove(panelName);});}}//得到面板public T GetPanel<T>() where T : BasePanel{string panelName = typeof(T).Name;if (panelDic.ContainsKey(panelName)){return panelDic[panelName] as T;}//没有对应面板返回空return null;}
}
2、如何使用
创建一个测试的UI面板(随便乱拼),将他作为预设体
创建一个测试类
public class TestMain : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){UIManager.Instance.ShowPanel<TestPanel>();}// Update is called once per framevoid Update(){}
}
启动发现已经动态创建了Canvas和对应面板