Unity界面管理器封装
1、使用场景:
UI面板显示/隐藏,适用于同一个场景内跳转面板
2、实现思路:
将显示UI所需要的画布Canvas和EventSystem设置为跨场景不销毁对象,将其他ui面板全部设置为预制体,用户即可自定义动态加载面板显示或者隐藏
3、具体实现:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; /// <summary> /// 层级 枚举 /// </summary> public enum UILevel { Bot, Mid, Top, System } /// <summary> /// UI界面管理器:处理面板显示/隐藏 /// </summary> public class UIManager : SingletonBase<UIManager> { private Transform bot;//最低层级 private Transform mid;//中间层级 private Transform top;//最上层级 private Transform system;//系统层级 //字典 用来保存、管理 面板 private Dictionary<string, UIBasePanel> panelDict = new Dictionary<string, UIBasePanel>(); public UIManager() { GameObject canvasObj = ResController.GetInstance().LoadAsset<GameObject>("UIPanel/Canvas");//找到画布 GameObject eventSystem = ResController.GetInstance().LoadAsset<GameObject>("UIPanel/EventSystem");//找到系统的ui事件检测 //设置过场景不销毁 GameObject.DontDestroyOnLoad(canvasObj); GameObject.DontDestroyOnLoad(eventSystem); //找到四个层级 bot = canvasObj.transform.Find("bot"); mid = canvasObj.transform.Find("mid"); top = canvasObj.transform.Find("top"); system = canvasObj.transform.Find("system"); } /// <summary> /// 加载面板 显示 /// </summary> /// <typeparam name="T">面板挂载的脚本类型</typeparam> /// <param name="panelPath">面板路径</param> /// <param name="level">面板需要显示在的层级</param> /// <param name="callBack">面板挂载脚本要执行的逻辑</param> public void ShowUIPanel<T>(string panelPath,UILevel level=UILevel.Bot,UnityAction<T> callBack=null) where T:UIBasePanel { //第二次加载同一个面板时 string s = panelPath.Split('/')[panelPath.Split('/').Length - 1]; if (panelDict.ContainsKey(s)) { if (callBack != null) callBack(panelDict[s] as T); return; } //异步加载面板预制体 ResController.GetInstance().LoadAssetAsync<GameObject>(panelPath, (obj) => { //指定层级 Transform father = null; switch (level) { case UILevel.Mid: father = mid; break; case UILevel.Top: father = top; break; case UILevel.System: father = system; break; default: father = bot; break; } //设置层级 obj.transform.SetParent(father); //设置面板位置 obj.transform.localPosition = Vector3.zero; obj.transform.localScale = Vector3.one; (obj.transform as RectTransform).offsetMax = Vector2.zero; (obj.transform as RectTransform).offsetMin = Vector2.zero; //获取面板 继承了UIBasePanel 的脚本 T panel=obj.GetComponent<T>(); //执行回调函数 if (callBack != null) { callBack(panel); } //将创建的面板加入到字典 panelDict.Add(s, panel); }); } /// <summary> /// 隐藏面板 /// </summary> /// <param name="name">面板名称</param> public void HideUIPanel(string name) { if (panelDict.ContainsKey(name)) { //销毁面板 字典移除 GameObject.Destroy(panelDict[name].gameObject); panelDict.Remove(name); } } }
测试:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class UIShow : MonoBehaviour { void Start () { UIManager.GetInstance().ShowUIPanel<UITest>("UIPanel/LoginPanel", UILevel.Top, LoginSuccess);//加载显示面板 } private void LoginSuccess(UITest test) { Debug.Log("登入界面加载完成"); Invoke("DestoryPanel",4); } private void DestoryPanel() { UIManager.GetInstance().HideUIPanel("LoginPanel");//隐藏面板 } }
效果:
评论