本节今天和大家分享一个Unity中的UI框架,一款游戏中的界面是非常多的,少则几十多则上百,如此众多的界面我们如何去控制其何时加载何时关闭,这就需要我们搭建一个UI框架来管理界面,所有的界面的创建和隐藏都是通过该UI框架完成。
首先需要创建一个UIManager脚本文件,并将其设置为单例模式,如下:
public class UIManager : MonoBehaviour { public static UIManager instance; public static UIManager getInstance() { return instance; } void Awake() { instance = this; } }
接下来添加两个画布游戏对象,UICanvasObj画布为普通画布,一般界面都放在该画布下,TopCanvasObj画布的order会高于UICanvasObj,一般会将加载界面放在该画布下,这样就可以保证无论何时加载界面都始终在所有界面的最上面显示。
public static GameObject UICanvasObj;
public static GameObject TopCanvasObj;
Awake方法中添加如下代码:
UICanvasObj = GameObject.Find("Canvas");
TopCanvasObj = GameObject.Find("TopCanvas");
画布order设置如下图:
接下来定义一个字典用来存储当前已加载界面对象,这样当第一次创建界面时添加到字典中,后续控制界面显示与隐藏直接通过字典获取即可,避免每次都重复创建界面,消耗资源,代码如下:
private Dictionary<PanelEnum, Transform> UIModules;
Awake中添加以下代码:
UIModules = new Dictionary<PanelEnum, Transform>();
由于切换界面过程中不能销毁当前管理类所以还需添加以下代码在Awake中:
DontDestroyOnLoad(TopCanvasObj);
DontDestroyOnLoad(gameObject);
接下来就可以添加LoadAndShowPanelByName方法来创建界面了,该方法主要从Resource文件夹中加载界面并添加到字典中,如果已经在字典中存在那么直接获取并返回,代码如下:
/// <summary> /// 根据界面名称加载并显示UI界面 /// </summary> /// <param name="panelName"></param> public void LoadAndShowPanelByName(PanelEnum panelName, PanelCanvas panelCanvas) { if (UIModules.ContainsKey(panelName)) { Transform panel = null; UIModules.TryGetValue(panelName, out panel); if (panel == null) { //如果字典中key值对应的value值已销毁那么将键值对移除,重新创建该界面 UIModules.Remove(panelName); } else { panel.gameObject.SetActive(true); return; } } GameObject parentCanvas = null; switch (panelCanvas) { case PanelCanvas.UICanvasObj: if (UICanvasObj == null) { UICanvasObj = GameObject.Find("Canvas"); } parentCanvas = UICanvasObj; break; case PanelCanvas.TopCanvasObj: if (TopCanvasObj == null) { TopCanvasObj = GameObject.Find("TopCanvas"); } parentCanvas = TopCanvasObj; break; } string panelResource = uiPath + "/" + panelName.ToString(); GameObject panelGO = Resources.Load(panelResource) as GameObject; panelGO = Instantiate(panelGO, parentCanvas.transform);//实例化预制体 panelGO.transform.localPosition = Vector3.zero; panelGO.gameObject.SetActive(true); UIModules.Add(panelName, panelGO.transform); } 接下来添加HidePanelByName方法来隐藏界面,代码如下: /// <summary> /// 根据界面名称隐藏UI界面 /// </summary> /// <param name="panelName"></param> public void HidePanelByName(PanelEnum panelName) { Transform panel = null; if (!UIModules.ContainsKey(panelName)) { return; } UIModules.TryGetValue(panelName, out panel); panel.gameObject.SetActive(false); } 也可继续进行扩展,如果想要获取某个界面的对象可以继续添加GetPanelByName方法,调用该方法后可以返回界面对象,代码如下: /// <summary> /// 根据界面名称查找指定panel对象 /// </summary> /// <param name="panelName"></param> /// <returns></returns> public Transform GetPanelByName(PanelEnum panelName) { Transform panel = null; if (UIModules.ContainsKey(panelName)) { UIModules.TryGetValue(panelName,out panel); } return panel; }
这样一个基础的UI管理框架就搭建完成了,后续可以继续进行扩展,今天的分享就到这里,大家有什么问题可以私聊我。