简介:
1,通过Resources.Load加载
2,使用字典进行缓存
3,使用重载进行动静分离,创建新画布。
4,单例模式
5,核心功能:(1)打开面板 (2)关闭面板 (3)检测配置路径 (4)检测缓存
UIManager.cs
//框架使用说明
//在UIConst中定义要加载预制体的名字。
//在InitDicts的pathDict进行配置路径
//需要配置路径和面板名称
//在任何地方调用UIManager.Instance.OpenPanel("PanelName", true)即可
//第一个参数是面板名称,第二个参数表示是否创建一个新的动态画布用于作为面板的根节点
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager
{
private static UIManager _instance;
private Transform _uiRoot;
// 路径配置字典
private Dictionary<string, string> pathDict;
// 预制件缓存字典
private Dictionary<string, GameObject> prefabDict;
// 已打开界面的缓存字典
public Dictionary<string, BasePanel> panelDict;
public static UIManager Instance
{
get
{
if (_instance == null)
{
_instance = new UIManager();
}
return _instance;
}
}
public Transform UIRoot
{
get
{
if (_uiRoot == null)
{
_uiRoot = GameObject.Find("StaticCanvas").transform;
return _uiRoot;
};
return _uiRoot;
}
}
private UIManager()
{
InitDicts();
}
/// <summary>
/// 初始化字典。预制体字典用于缓存,面板字典用于检测面板是否打开,路径面板用于配置路径。
/// </summary>
private void InitDicts()
{
prefabDict = new Dictionary<string, GameObject>();
panelDict = new Dictionary<string, BasePanel>();
pathDict = new Dictionary<string, string>()
{
{UIConst.Start_Panel,"Start/Start_Panel" },
{UIConst.Start_Panel_1,"Start/Start_Panel_1" },
{UIConst.Start_Panel_2,"Start/Start_Panel_2" },
{UIConst.Start_Panel_3,"Start/Start_Panel_3" },
{UIConst.Start_Panel_4,"Start/Start_Panel_4" },
{UIConst.Start_Panel_5,"Start/Start_Panel_5" },
{UIConst.Start_Panel_6,"Start/Start_Panel_6" },
{UIConst.Start_Panel_7,"Start/Start_Panel_7" },
{UIConst.Start_Panel_8,"Start/Start_Panel_8" },
{UIConst.Start_Panel_9,"Start/Start_Panel_9" },
{UIConst.Start_Panel_10,"Start/Start_Panel_10" },
{UIConst.Main_Panel,"Main_Panel" },
{UIConst.Zha_Ying_Panel,"Zha_Ying_Panel" },
{UIConst.Troops_Panel,"Troops_Panel" },
{UIConst.Chracter_Panel,"Chracter_Panel" },
{UIConst.Item_Panel,"Item_Panel" },
{UIConst.JiLu_Panel,"JiLu_Panel" },
{UIConst.DuDang_Panel,"Start/DuDang_Panel" }
};
}
/// <summary>
/// 打开面板。第一个参数为面板名字,第二个参数是面板是否位于动态面板,如果没有则创建一个动态面板。使用字典判断该面板是否已经打开。根据配置路径找到面板,配置路径不正确,会Debug.LogError
/// </summary>
/// <param name="name"></param>
/// <param name="isDynamicCanvas"></param>
/// <returns></returns>
public BasePanel OpenPanel(string name, bool isDynamicCanvas)
{
BasePanel panel = null;
// 检查是否已打开
if (panelDict.TryGetValue(name, out panel))
{
Debug.LogError("界面已打开: " + name);
return null;
}
// 检查路径是否配置
string path = "";
if (!pathDict.TryGetValue(name, out path))
{
Debug.LogError("界面名称错误,或未配置路径: " + name);
return null;
}
// 使用缓存预制件
GameObject panelPrefab = null;
if (!prefabDict.TryGetValue(name, out panelPrefab))
{
string realPath = "Prefab/" + path;
//使用Resources.Load动态加载
panelPrefab = Resources.Load<GameObject>(realPath) as GameObject;
if (panelPrefab.GetComponent<BasePanel>() == null)
panelPrefab.AddComponent<BasePanel>();
prefabDict.Add(name, panelPrefab);
}
GameObject panelObject;
if (isDynamicCanvas == true)
{
Canvas canvas;
GameObject DynamicCanvas = GameObject.Find("DynamicCanvas");
if (DynamicCanvas == null)
{
//创建动态画布画布
GameObject canvasGo = new GameObject("DynamicCanvas");
canvas = canvasGo.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvasGo.AddComponent<CanvasScaler>();
canvasGo.AddComponent<GraphicRaycaster>();
panelObject = GameObject.Instantiate(panelPrefab, canvas.transform, false);
}
else
{
panelObject = GameObject.Instantiate(panelPrefab, DynamicCanvas.transform, false);
}
}
else
{
panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
}
// 打开界面
panel = panelObject.GetComponent<BasePanel>();
panelDict.Add(name, panel);
panel.OpenPanel(name);
return panel;
}
/// <summary>
/// 关闭面板。参数是面板名字。查看字典该面板没有打开就return,否则关闭该面板。
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public BasePanel OpenPanel(string name)
{
OpenPanel(name, false);
return null;
}
public bool ClosePanel(string name)
{
BasePanel panel = null;
if (!panelDict.TryGetValue(name, out panel))
{
Debug.LogError("界面未打开: " + name);
return false;
}
panel.ClosePanel();
//panelDict.Remove(name);不移除缓存 合适的时候移除
return true;
}
public void ShowTip(string tip)
{
// MenuTipPanel menuTipPanel = OpenPanel(UIConst.MenuTipPanel) as MenuTipPanel;
// menuTipPanel.InitTip(Globals.TipCreateOne);
}
}
/// <summary>
/// 该结构体用于存储面板名字
/// </summary>
public struct UIConst
{
// menu panels
public const string Start_Panel = "Start_Panel";
public const string Start_Panel_1 = "Start_Panel_1";
public const string Start_Panel_2 = "Start_Panel_2";
public const string Start_Panel_3 = "Start_Panel_3";
public const string Start_Panel_4 = "Start_Panel_4";
public const string Start_Panel_5 = "Start_Panel_5";
public const string Start_Panel_6 = "Start_Panel_6";
public const string Start_Panel_7 = "Start_Panel_7";
public const string Start_Panel_8 = "Start_Panel_8";
public const string Start_Panel_9 = "Start_Panel_9";
public const string Start_Panel_10 = "Start_Panel_10";
public const string Main_Panel = "Main_Panel";
public const string Zha_Ying_Panel = "Zha_Ying_Panel";
public const string Troops_Panel = "Troops_Panel";
public const string Chracter_Panel = "Chracter_Panel";
public const string Item_Panel = "Item_Panel";
public const string JiLu_Panel = "JiLu_Panel";
public const string DuDang_Panel = "DuDang_Panel";
}
BasePanel.cs
using UnityEngine;
public class BasePanel : MonoBehaviour
{
protected bool isRemove = false;
protected new string name;
public virtual void SetActive(bool active)
{
gameObject.SetActive(active);
}
//打开面板
public virtual void OpenPanel(string name)
{
this.name = name;
SetActive(true);
}
//按钮事件打开面板
public virtual void OpenNewPanel(string name)
{
UIManager.Instance.OpenPanel(name);
}
//关闭面板
public virtual void ClosePanel()
{
isRemove = true;
SetActive(false);
Destroy(gameObject);
if (UIManager.Instance.panelDict.ContainsKey(name))
{
UIManager.Instance.panelDict.Remove(name);
}
}
}