Files
5.24BuYu/Assets/Framework/Tool/UITool/UIManager.cs
T
2025-12-11 16:40:24 +08:00

263 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System;
using UnityEngine;
using System.Collections;
using Unity.VisualScripting.FullSerializer;
using UnityEngine.AddressableAssets;
using System.Net;
using UnityEngine.ResourceManagement.AsyncOperations;
//ui面板枚举 这里要求分类 Main *00 *00-*99 整数为主界面尾数为子界面
public enum UIPanel
{
None = 0,
LoginPanel = 10,
#region 100-199HomePanel
//100-150center界面
HomeMainPanel = 100,
SelectRoomLevelPenel = 101,
//150-199 Margin界面
VIPPenel = 151,
JJJPenel = 152,
HDPenel = 153,
MonthCardPanel=161,
BackPackPanel=162,
AnnouncementPanel=163,
RankPanel=164,
EmailPanel=165,
SafeBoxPanel=166,
ServicePanel=167,
ShopPanel=168,
TurretPanel=181,
ZSPanel=182,
#endregion
}
public class UIManager : MonoSingleton<UIManager>
{
// 已加载的面板实例 主面板列表
private readonly Dictionary<UIPanel, UIBase> panels = new Dictionary<UIPanel, UIBase>();
[SerializeField] private UIPanelAddressConfig config;
// 父节点(可指定到 Canvas 下某个容器)
[SerializeField] private Transform uiRoot;
private Dictionary<UIPanel, string> addressMap = new Dictionary<UIPanel, string>(); //第二种加载
protected override void Awake()
{
base.Awake();
foreach (var entry in config.panels)
{
if (!addressMap.ContainsKey(entry.type))
addressMap.Add(entry.type, entry.address);
}
if (uiRoot == null)
{
var canvas = FindObjectOfType<Canvas>();
uiRoot = canvas != null ? canvas.transform : transform;
}
}
/// <summary>
/// 同步显示(若未实例化则立即实例化)
/// </summary>
public UIBase Show(UIPanel type, object args = null)
{
if (addressMap.ContainsKey(type))
{
// 模拟异步:此处可替换为真正的资源加载(Addressables/AssetBundle)
var handle = Addressables.LoadAsset<GameObject>(addressMap[type]);
if (handle.Status == AsyncOperationStatus.Succeeded)
{
var panel = GetOrCreatePanel(type, handle.Result);
panel?.Show(args);
return panel;
}
else
{
Debug.LogError($"Failed to load UI prefab for {type}");
return null;
}
}
else
{
Debug.Log("加载失败" + type.ToString() + "不存在");
return null;
}
}
/// <summary>
/// Addressables/异步加载 关闭另外一个面板
/// </summary>
public Coroutine ShowAsync(UIPanel type, UIPanel isClosePanel,object args = null, Action<UIBase> onShown = null)
{
if (isClosePanel == 0)
return StartCoroutine(CoShow(type, args, onShown));
else
{
return StartCoroutine(CoShow(type, args, onShown, isClosePanel));
}
}
/// <summary>
/// Addressables/异步加载
/// </summary>
public Coroutine ShowAsync(UIPanel type, object args = null, Action<UIBase> onShown = null)
{
return StartCoroutine(CoShow(type, args, onShown));
}
private IEnumerator CoShow(UIPanel type, object args, Action<UIBase> onShown)
{
if (addressMap.ContainsKey(type))
{
// 模拟异步:此处可替换为真正的资源加载(Addressables/AssetBundle)
var handle = Addressables.LoadAssetAsync<GameObject>(addressMap[type]);
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
var panel = GetOrCreatePanel(type, handle.Result);
panel?.Show(args);
onShown?.Invoke(panel);
}
else
{
Debug.LogError($"Failed to load UI prefab for {type}");
}
}
else
{
Debug.Log("加载失败" + type.ToString() + "不存在");
yield break;
}
}
private IEnumerator CoShow(UIPanel type, object args, Action<UIBase> onShown,UIPanel uIPanel)
{
if (addressMap.ContainsKey(type))
{
// 模拟异步:此处可替换为真正的资源加载(Addressables/AssetBundle)
var handle = Addressables.LoadAssetAsync<GameObject>(addressMap[type]);
yield return handle;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
var panel = GetOrCreatePanel(type, handle.Result);
panel?.Show(args);
onShown?.Invoke(panel);
}
else
{
Debug.LogError($"Failed to load UI prefab for {type}");
UIManager.Instance.Close(uIPanel);
}
}
else
{
Debug.Log("加载失败" + type.ToString() + "不存在");
UIManager.Instance.Get<UIBase>(uIPanel)?.Show();
yield break;
}
}
/// <summary>
/// 隐藏
/// </summary>
/// <param name="type"></param>
public void Hide(UIPanel type)
{
if (panels.TryGetValue(type, out var panel) && panel != null)
{
panel.Hide();
}
else
{
Debug.LogWarning($"Hide failed: panel {type} not found.");
}
}
public bool IsShown(UIPanel type)
{
return panels.TryGetValue(type, out var panel) && panel.gameObject.activeSelf;
}
/// <summary>
/// 获取uiPanel 有就返回没有就返回空
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <returns></returns>
public T Get<T>(UIPanel type) where T : UIBase
{
return panels.TryGetValue(type, out var panel) ? panel as T : null;
}
/// <summary>
/// 获取或者创建panel
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private UIBase GetOrCreatePanel(UIPanel type, GameObject obj)
{
if (panels.TryGetValue(type, out var existing) && existing != null)
return existing;
if (!addressMap.TryGetValue(type, out var prefabPath) || prefabPath == null)
{
Debug.LogError($"No prefab registered for {type}");
return null;
}
var instance = Instantiate(obj, uiRoot).GetComponent<UIBase>();
instance.name = $"{type}_Panel";
instance.Init(type);
panels[type] = instance;
return instance;
}
/// <summary>
/// 关闭并销毁某个面板实例(内存回收)
/// </summary>
public void Close(UIPanel type)
{
if (panels.TryGetValue(type, out var panel) && panel != null)
{
panel.Hide();
Destroy(panel.gameObject);
}
panels.Remove(type);
}
/// <summary>
/// 关闭并销毁所有面板
/// </summary>
public void CloseAll()
{
foreach (var kv in panels)
{
if (kv.Value != null)
{
kv.Value.Hide();
Destroy(kv.Value.gameObject);
}
}
panels.Clear();
}
}