赞
踩
1.引入
前面我们用一个UI基类来对一个Panel下的所有组件进行管理,现在我们要对一个Canvas下的所有Panel进行统一管理,即显示和隐藏Panel
一般有两种办法进行显示和隐藏Panel:
1.设置Panel的Active(SetActive)为true或者false,即显示或隐藏Panel
2.将Panel做成预设体,进行实例化和销毁Panel
前者如果面板过多,会占用过多的内存,所以我们选择后者
2.思路
写一个UIManager
为了统一管理(有时需要显示的Panel不止一个),我们用一个字典来存放显示的Panel,即是:
Dictionary<string, PanelBase> dic = new Dictionary<string, PanelBase>();
注:PanelBase为前面的UI基类,即所有Panel脚本的父类
2.1显示面板的实现:
2.1.1那么我们在实例化Panel时候也需要考虑层级问题,为此,我们将Canvas进行如下操作:
此处的Bottom、Medium、Top,System分别对应显示的不同层级。在实例化时只要放在需要显示的对应层级下(作为对应层的子物体)
注:在hierarchy面板中的UI层越靠前越先渲染,即越底层,可能被遮挡。
为了方便,我们将Canvas和EventSystem也做成预设体,在UIManager的构造函数中实例化,因为是单例,所以只会被实例化一次,即Cavas和EventSystem也只会被实例化一次。
2.1.2 实例化面板后,我们通常要对面板的一些信息进行更新,所以函数的参数还可以设置一个委托在实例化后调用(因为此处是异步加载资源,所以在外部不知道什么时候加载完毕,需要专门设置一个参数调用实例化后的函数)
2.1.3 面板显示函数:
/// <summary> /// 显示面板 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name"></param> /// <param name="layout"></param> /// <param name="action"></param> public void ShowPanel<T>(string name,UI_Layout layout= UI_Layout.SYSTEM, UnityAction<T> action=null) where T: PanelBase { //如果字典中存在该面板,即已经在显示该面板 if(dic!=null&&dic.ContainsKey(name)) { T t = dic[name].GetComponent<T>(); if(action!=null) action(t); return; } //确定显示的层级 Transform father= canvas.Find("System"); ResourcesManager.GetInstance().LoadResourceAsync<GameObject>("UI/" + name, (o) => { switch(layout) { case UI_Layout.BOTTOM: father = canvas.Find("Bottom");break; case UI_Layout.MEDIUM: father = canvas.Find("Medium");break; case UI_Layout.TOP: father = canvas.Find("Top");break; } //设置显示的参数 o.name = name; o.transform.SetParent(father); o.transform.localPosition = Vector3.zero; o.transform.localScale = Vector3.one; (o.transform as RectTransform).offsetMax = Vector2.zero; (o.transform as RectTransform).offsetMin = Vector2.zero; //执行显示后的操作 T t = o.GetComponent<T>(); if(action!=null) action(t); //存储到字典中[注意此处只存脚本是因为我们对panel的操作一般体现在调用panel的方法] dic.Add(name, t); }); }
2.2隐藏面板
只需进行销毁和从字典中移除的操作即可。
3.所有代码
public class UIManager : SingeCaseBase<UIManager> { //面板层级 public enum UI_Layout { TOP, BOTTOM, MEDIUM, SYSTEM, }; Transform canvas; /// <summary> /// 创建Canvas和EventSystem /// </summary> public UIManager() { canvas = ResourcesManager.GetInstance().LoadResource<GameObject>("UI/Canvas").transform; GameObject.DontDestroyOnLoad(canvas); GameObject eventSystem = ResourcesManager.GetInstance().LoadResource<GameObject>("UI/EventSystem"); GameObject.DontDestroyOnLoad(eventSystem); } Dictionary<string, PanelBase> dic = new Dictionary<string, PanelBase>(); /// <summary> /// 显示面板 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name"></param> /// <param name="layout"></param> /// <param name="action"></param> public void ShowPanel<T>(string name,UI_Layout layout= UI_Layout.SYSTEM, UnityAction<T> action=null) where T: PanelBase { //如果字典中存在该面板,即已经在显示该面板 if(dic!=null&&dic.ContainsKey(name)) { T t = dic[name].GetComponent<T>(); if(action!=null) action(t); return; } //确定显示的层级 Transform father= canvas.Find("System"); ResourcesManager.GetInstance().LoadResourceAsync<GameObject>("UI/" + name, (o) => { switch(layout) { case UI_Layout.BOTTOM: father = canvas.Find("Bottom");break; case UI_Layout.MEDIUM: father = canvas.Find("Medium");break; case UI_Layout.TOP: father = canvas.Find("Top");break; } //设置显示的参数 o.name = name; o.transform.SetParent(father); o.transform.localPosition = Vector3.zero; o.transform.localScale = Vector3.one; (o.transform as RectTransform).offsetMax = Vector2.zero; (o.transform as RectTransform).offsetMin = Vector2.zero; //执行显示后的操作 T t = o.GetComponent<T>(); if(action!=null) action(t); //存储到字典中[注意此处只存脚本是因为我们对panel的操作一般体现在调用panel的方法] dic.Add(name, t); }); } /// <summary> /// 隐藏面板 /// </summary> /// <param name="name"></param> public void HidePanel(string name) { if(dic.ContainsKey(name)) { //销毁并移除 GameObject.Destroy(dic[name].gameObject); dic.Remove(name); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。