263 lines
7.2 KiB
C#
263 lines
7.2 KiB
C#
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();
|
||
}
|
||
}
|