406 lines
12 KiB
C#
406 lines
12 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;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
using UnityEngine.Video;
|
||
//ui面板枚举 这里要求分类 Main *00 *00-*99 整数为主界面尾数为子界面
|
||
public enum UIPanel
|
||
{
|
||
None=9999,
|
||
LoginPanel = 0,
|
||
#region 90-99loginPanel
|
||
LoginEnterPanel=90,
|
||
ResetPasswordPanel=91,
|
||
RegisterPanel = 92,
|
||
#endregion
|
||
|
||
HomeMainPanel = 1,
|
||
MainGamePanelDefault = 2,
|
||
MainGamePanelFLZY = 3,
|
||
MainGamePanelTGXX = 4,
|
||
MainGamePanelZGXQ = 5,
|
||
MainGamePanelXJMH = 6,
|
||
MainGamePanelHHWK = 7,
|
||
MainGamePanelJQQD = 8,
|
||
#region 100-199HomePanel
|
||
//100-140center界面
|
||
|
||
SelectRoomLeavePenel = 101,
|
||
MySelectRoomPanel = 102,//这个界面没有加载到子界面中直接在选择房间的界面中使用
|
||
|
||
|
||
//140-199 Margin界面
|
||
UserInfo = 141,
|
||
|
||
VIPPenel = 151,
|
||
JJJPenel = 152,
|
||
ActivityPenel = 153,
|
||
|
||
MonthCardPanel = 161,
|
||
BackPackPanel = 162,
|
||
AnnouncementPanel = 163,
|
||
RankPanel = 164,
|
||
EmailPanel = 165,
|
||
SafeBoxPanel = 166,
|
||
ServicePanel = 167,
|
||
ShopPanel = 168,
|
||
|
||
TurretPanel = 181,
|
||
ZSPanel = 182,
|
||
|
||
SettingPanel = 199,
|
||
#endregion
|
||
#region 200-299 Game界面
|
||
ZGXQDistrict= 251,
|
||
ZGXQCreateRoom=252,
|
||
ZGXQSelectCoin=2521,
|
||
ZGXQGameExplain=2522,
|
||
ZGXQJoinGame=253,
|
||
ZGXQWin = 254,
|
||
ZGXQDefeated= 255,
|
||
ZGXQSetting=256,
|
||
ZGXQHint=257,
|
||
ZGXQIntroduce = 258,
|
||
#endregion
|
||
|
||
|
||
|
||
}
|
||
|
||
public class UIManager : MonoSingleton<UIManager>
|
||
{
|
||
// 已加载的面板实例 主面板列表
|
||
private readonly Dictionary<UIPanel, UIBase> panels = new Dictionary<UIPanel, UIBase>();
|
||
[SerializeField] private UIPanelAddressConfig config;
|
||
|
||
|
||
// 父节点(可指定到 Canvas 下某个容器)
|
||
[SerializeField] public Transform uiRoot;
|
||
|
||
private Dictionary<UIPanel, string> addressMap = new Dictionary<UIPanel, string>(); //第二种加载
|
||
public GameObject loadPanel;
|
||
public LoadingPanel ShowLoadPanel(VideoClip videoClip, Action action=null)
|
||
{
|
||
GameObject load = Instantiate(loadPanel, uiRoot);
|
||
var loadScript = load.GetComponent<LoadingPanel>();
|
||
load.transform.GetChild(0).gameObject.SetActive(true);
|
||
loadScript.player.clip = videoClip;
|
||
loadScript.player.Play();
|
||
loadScript.actionEnd = action;
|
||
return loadScript;
|
||
}
|
||
public LoadingPanel ShowLoadPanel(Sprite sprite, Action action = null)
|
||
{
|
||
GameObject load = Instantiate(loadPanel, uiRoot);
|
||
var loadScript = load.GetComponent<LoadingPanel>();
|
||
load.transform.GetChild(1).gameObject.SetActive(true);
|
||
loadScript.image_Bg.sprite = sprite;
|
||
loadScript.actionEnd = action;
|
||
return loadScript;
|
||
|
||
}
|
||
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 T Show<T>(UIPanel type, object args = null) where T : UIBase
|
||
{
|
||
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 (T)panel;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"Failed to load UI prefab for {type}");
|
||
|
||
return null;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("加载失败" + type.ToString() + "不存在");
|
||
return null;
|
||
}
|
||
}
|
||
/// <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)
|
||
{
|
||
|
||
return StartCoroutine(CoShow(type, args, onShown, isClosePanel));
|
||
|
||
}
|
||
/// <summary>
|
||
/// Addressables/异步加载
|
||
/// </summary>
|
||
public Coroutine ShowAsync(UIPanel type, object args = null, Action<UIBase> onShown = null,float YCTime=0)
|
||
{
|
||
return StartCoroutine(CoShow(type, args, onShown, YCTime));
|
||
}
|
||
public GameObject BoardPanelParefab;
|
||
public GameObject BoardPanelParefabGongGao;
|
||
public void ShowBoardError(string str)
|
||
{
|
||
|
||
StartCoroutine(IEShowBoard(str));
|
||
|
||
}
|
||
public void ShowBoardGongGao(string str)
|
||
{
|
||
|
||
StartCoroutine(IEShowBoardGongGao(str));
|
||
|
||
}
|
||
public float speedGongGao;
|
||
IEnumerator IEShowBoardGongGao(string str)
|
||
{
|
||
var obj = Instantiate(BoardPanelParefabGongGao, uiRoot);
|
||
var gg = obj.transform.GetChild(0).GetChild(0).GetComponent<RectTransform>();
|
||
gg.GetComponent<TextMeshProUGUI>().text = str;
|
||
TextMeshProUGUI t = obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
|
||
Image i = obj.GetComponent<Image>();
|
||
while (true)
|
||
{
|
||
gg.Translate(Vector3.left*speedGongGao);
|
||
if (gg.anchoredPosition3D.x<=-gg.sizeDelta.x)
|
||
{
|
||
break;
|
||
}
|
||
yield return null;
|
||
}
|
||
Destroy(obj);
|
||
|
||
}
|
||
IEnumerator IEShowBoard(string str)
|
||
{
|
||
var obj = Instantiate(BoardPanelParefab, uiRoot);
|
||
obj.transform.SetAsLastSibling();
|
||
obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = str;
|
||
yield return new WaitForSeconds(1);
|
||
float a = 1;
|
||
Color c;
|
||
TextMeshProUGUI t = obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>();
|
||
Image i = obj.GetComponent<Image>();
|
||
while (true)
|
||
{
|
||
a-=Time.deltaTime;
|
||
yield return null;
|
||
c = i.color;
|
||
c.a=a;
|
||
i.color = c;
|
||
|
||
c = t.color;
|
||
c.a = a;
|
||
t.color = c;
|
||
if (a<0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
Destroy(obj);
|
||
|
||
}
|
||
public void StopShowPanel()
|
||
{
|
||
StopAllCoroutines();
|
||
}
|
||
private IEnumerator CoShow(UIPanel type, object args, Action<UIBase> onShown, float YCtime)
|
||
{
|
||
yield return new WaitForSeconds(YCtime);
|
||
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 ClosePanel)
|
||
{
|
||
|
||
if (addressMap.ContainsKey(type))
|
||
{
|
||
|
||
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);
|
||
UIManager.Instance.Close(ClosePanel);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"Failed to load UI prefab for {type}");
|
||
UIManager.Instance.Get<UIBase>(ClosePanel)?.Show();
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("加载失败" + type.ToString() + "不存在");
|
||
UIManager.Instance.Get<UIBase>(ClosePanel)?.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();
|
||
}
|
||
}
|