4.UI管理器
4.1 知识点
UI管理器类图
创建私有静态 UIManager 脚本,搞成单例
public class UIManager
{
private static UIManager instance = new UIManager();
public static UIManager Instance => instance;
}
创建私有的字典 panelDic,用于存储正在显示的面板,键为面板名字,值为面板的实例。
//用于存储显示着的面板的 每显示一个面板 就会存入这个字典
//隐藏面板时 直接获取字典中的对应面板 进行隐藏
private Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();
创建私有的变量 canvasTrans,用于存储场景中的 Canvas 对象的 Transform 组件。在场景中创建一个Canvas,把EventSystem拖入作为子物体,调整好Canvas模式和尺寸自适应,拖到Resources下的UI文件夹作为预制体。在私有的构造函数中,实例化 Canvas 对象并获取其 Transform 组件,并设置为 canvasTrans 的值。通过 GameObject.Instantiate 方法加载预设体并得到 GameObject 对象,然后使用 SetParent 方法将其放置在 Canvas 对象下面,最后调用 DontDestroyOnLoad 方法保证在场景切换时不会被销毁。
//场景中的 Canvas对象 用于设置为面板的父对象
private Transform canvasTrans;
private UIManager()
{
//得到场景中的Canvas对象
GameObject canvas = GameObject.Instantiate(Resources.Load<GameObject>("UI/Canvas"));
canvasTrans = canvas.transform;
//通过过场景不移除该对象 保证这个游戏过程中 只有一个 canvas对象
GameObject.DontDestroyOnLoad(canvas);
}
ShowPanel 方法用于显示面板。首先获取要显示面板的名字panelName。然后判断字典中是否已经有该面板的实例,如果有则直接返回对应类型的面板实例。如果没有,则根据面板名字动态加载预设体,并设置父对象为 Canvas。接着获取面板的组件类型并保存为 T 类型的变量 panel,将面板实例添加到字典中,最后调用面板的 ShowMe 方法显示面板,并返回面板实例。
//显示面板
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;
}
HidePanel 方法用于隐藏面板。首先根据泛型得到要隐藏面板的名字 panelName,然后判断字典中是否存在该面板实例。如果存在,则根据参数 isFade 判断是否要进行淡出效果。如果需要淡出效果,则调用面板的 HideMe 方法,并将删除面板的操作作为回调函数传入,在透明度为0时执行删除面板的操作;如果不需要淡出效果,则直接删除面板。最后从字典中移除面板实例。
/// <summary>
/// 隐藏面板
/// </summary>
/// <typeparam name="T">面板类名</typeparam>
/// <param name="isFade">是否淡出完毕过后才删除面板 默认是ture</param>
public void HidePanel<T>(bool isFade = true) where T:BasePanel
{
//根据泛型得名字
string panelName = typeof(T).Name;
//判断当前显示的面板 有没有你想要隐藏的
if( panelDic.ContainsKey(panelName) )
{
if( isFade )
{
//就是让面板 淡出完毕过后 再删除它
panelDic[panelName].HideMe(() =>
{
//删除对象
GameObject.Destroy(panelDic[panelName].gameObject);
//删除字典里面存储的面板脚本
panelDic.Remove(panelName);
});
}
else
{
//删除对象
GameObject.Destroy(panelDic[panelName].gameObject);
//删除字典里面存储的面板脚本
panelDic.Remove(panelName);
}
}
}
GetPanel 方法用于获取面板实例。首先根据泛型得到要获取面板的名字 panelName,然后判断字典中是否存在该面板实例。如果存在,则将其转换为 T 类型并返回;如果不存在,则返回空。
//得到面板
public T GetPanel<T>() where T:BasePanel
{
string panelName = typeof(T).Name;
if (panelDic.ContainsKey(panelName))
return panelDic[panelName] as T;
//如果没有对应面板显示 就返回空
return null;
}
4.2 知识点代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager
{
private static UIManager instance = new UIManager();
public static UIManager Instance => instance;
//用于存储显示着的面板的 每显示一个面板 就会存入这个字典
//隐藏面板时 直接获取字典中的对应面板 进行隐藏
private Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();
//场景中的 Canvas对象 用于设置为面板的父对象
private Transform canvasTrans;
private UIManager()
{
//得到场景中的Canvas对象
GameObject canvas = GameObject.Instantiate(Resources.Load<GameObject>("UI/Canvas"));
canvasTrans = 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>
/// <param name="isFade">是否淡出完毕过后才删除面板 默认是ture</param>
public void HidePanel<T>(bool isFade = true) where T:BasePanel
{
//根据泛型得名字
string panelName = typeof(T).Name;
//判断当前显示的面板 有没有你想要隐藏的
if( panelDic.ContainsKey(panelName) )
{
if( isFade )
{
//就是让面板 淡出完毕过后 再删除它
panelDic[panelName].HideMe(() =>
{
//删除对象
GameObject.Destroy(panelDic[panelName].gameObject);
//删除字典里面存储的面板脚本
panelDic.Remove(panelName);
});
}
else
{
//删除对象
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;
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com