Unity界面管理器封装
1、使用场景:
UI面板显示/隐藏,适用于同一个场景内跳转面板
2、实现思路:
将显示UI所需要的画布Canvas和EventSystem设置为跨场景不销毁对象,将其他ui面板全部设置为预制体,用户即可自定义动态加载面板显示或者隐藏
3、具体实现:
C#
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);
}
}
}
测试:
C#
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");//隐藏面板
}
}
效果:
评论