TestCodeStructure/Assets/Scripts/Project/ProjectBase/UIManager/UIManager.cs

173 lines
4.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
/// <summary>
/// 可以根据需求继续增加层级
/// </summary>
public enum E_UI_Layer
{
/// <summary>
/// 最下层
/// </summary>
Bot,
/// <summary>
/// 中间层
/// </summary>
Mid,
/// <summary>
/// 上层 加载页面
/// </summary>
Top,
/// <summary>
/// 最上层 系统层 警告、错误
/// </summary>
System,
}
/// <summary>
/// UI管理器
///
/// </summary>
public class UIManager
{
/// <summary>
/// 底层、中层、上层、系统层
/// </summary>
private readonly Transform[] layers;
/// <summary>
/// canvas
/// </summary>
public RectTransform canvas;
/// <summary>
/// 存储显示的panel
/// </summary>
private readonly Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();
/// <summary>
/// 构造函数
/// </summary>
public UIManager()
{
canvas = ResourcesManager.Load<GameObject>("UI/Base/Canvas").GetComponent<RectTransform>();
GameObject.DontDestroyOnLoad(canvas.gameObject);
layers = new Transform[]
{
canvas.transform.Find("Bot"),
canvas.transform.Find("Mid"),
canvas.transform.Find("Top"),
canvas.transform.Find("System")
};
}
/// <summary>
/// 显示面板 要求:面板类型和面板名称相同
/// </summary>
/// <typeparam name="T">面板类型 面板名称</typeparam>
/// <param name="layer">显示在哪一层</param>
/// <param name="action">加载完成后 要做的</param>
public void ShowPanel<T>(MonoBehaviour target, E_UI_Layer layer = E_UI_Layer.Mid, UnityAction<T> action = null) where T : BasePanel
{
string panelName = typeof(T).Name;
//重复调用问题 1 已经存在的panel
if (panelDic.TryGetValue(panelName, out var panel))
{
panel.ShowMe();
action?.Invoke(panel as T);
return;
}
string resourcePath = "UI/UIPanel/" + panelName;
//重复调用 同一帧调用多次问题
ResourcesManager.LoadAsync<GameObject>(target, resourcePath, (panelObj) =>
{
if (panelObj == null)
{
// 资源加载失败处理
Debug.LogError($"Failed to load panel: {panelName}");
return;
}
var uilayer = layers[(int)layer];
panelObj.transform.SetParent(uilayer);
panelObj.transform.localPosition = Vector3.zero;
panelObj.transform.localRotation = Quaternion.identity;
panelObj.transform.localScale = Vector3.one;
(panelObj.transform as RectTransform).offsetMax = Vector3.zero;
(panelObj.transform as RectTransform).offsetMin = Vector3.zero;
T panel = panelObj.GetComponent<T>();
panel.ShowMe();
action?.Invoke(panel);
panelDic.Add(panelName, panel);
});
}
/// <summary>
/// 隐藏面板
/// </summary>
/// <param name="panelName"></param>
public void HidePanel<T>() where T : BasePanel
{
string panelName = typeof(T).Name;
if (panelDic.ContainsKey(panelName))
{
panelDic[panelName].HideMe();
//GameObject.Destroy(panelDic[panelName].gameObject);
//panelDic.Remove(panelName);
}
else
{
Debug.Log("显示的面板中不存在要隐藏的面板!!!!");
}
}
/// <summary>
/// 获取一个已显示的面板
/// </summary>
/// <typeparam name="T">想要获取的面板脚本</typeparam>
/// <returns></returns>
public T GetPanel<T>() where T : BasePanel
{
string panelName = typeof(T).Name;
if (panelDic.ContainsKey(panelName))
{
return panelDic[panelName] as T;
}
return null;
}
/// <summary>
/// 获取UI面板层
/// </summary>
/// <param name="layer"></param>
/// <returns></returns>
public Transform GetLayer(E_UI_Layer layer)
{
// 使用数组简化 GetLayer 方法
return layers[(int)layer];
}
/// <summary>
/// 给控件添加自定义事件
/// </summary>
/// <param name="control">控件对象</param>
/// <param name="type">事件类型</param>
/// <param name="action">委托</param>
public void AddEventTriggerListener(UIBehaviour control, EventTriggerType type,
UnityAction<BaseEventData> action)
{
var eventTrigger = control.GetOrAddComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry() { eventID = type };
entry.callback.AddListener(action);
eventTrigger.triggers.Add(entry);
}
}