2025-12-19 14:44:14 +08:00
|
|
|
|
using UnityEngine;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using System;
|
2025-04-08 14:54:25 +08:00
|
|
|
|
using System.Collections.Generic;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
using System.IO;
|
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
using Object = UnityEngine.Object;
|
2023-10-19 15:00:19 +08:00
|
|
|
|
using PhxhSDK;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2023-10-19 15:00:19 +08:00
|
|
|
|
public partial class UIRoot : SingletonMono<UIRoot>
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
public Canvas RootCanvas;
|
|
|
|
|
|
// 所有UI的根节点
|
|
|
|
|
|
public GameObject Root;
|
|
|
|
|
|
public Camera UICamera;
|
2024-07-19 13:12:50 +08:00
|
|
|
|
public Camera UITopCamera;
|
|
|
|
|
|
public GameObject UITopRoot;
|
2025-12-19 16:15:25 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UI层级根节点字典(私有,通过方法访问)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Dictionary<UICanvasLayer, GameObject> _rootDic = new(6);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
2024-04-24 14:03:19 +08:00
|
|
|
|
// [Range(-5, 5)]
|
|
|
|
|
|
// public float offsetX = 1.32f;
|
|
|
|
|
|
// [Range(-5, 5)]
|
|
|
|
|
|
// public float offsetY = 1.26f;
|
|
|
|
|
|
// [Range(-5, 5)]
|
|
|
|
|
|
// public float offsetZ = 0.83f;
|
|
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
// Loading节点
|
|
|
|
|
|
//public GameObject mUILoading;
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试修复花屏的问题
|
|
|
|
|
|
bool isDirty = false;
|
|
|
|
|
|
Font dirtyFont = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
Object.DontDestroyOnLoad(this.gameObject);
|
|
|
|
|
|
|
2025-08-13 16:08:34 +08:00
|
|
|
|
// Font.textureRebuilt += delegate (Font font1)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// isDirty = true;
|
|
|
|
|
|
// dirtyFont = font1;
|
|
|
|
|
|
// };
|
2023-10-19 15:00:19 +08:00
|
|
|
|
|
2025-10-24 13:45:50 +08:00
|
|
|
|
// var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
2023-08-22 19:08:45 +08:00
|
|
|
|
//mUILoading.AddComponent(typeof(SliderZero));
|
2025-12-19 11:54:18 +08:00
|
|
|
|
var backGround = transform.Find("UIBackGround");
|
|
|
|
|
|
var normal = transform.Find("UINormal");
|
|
|
|
|
|
var foreGround = transform.Find("UIForeGround");
|
|
|
|
|
|
var tips = transform.Find("UITips");
|
|
|
|
|
|
var guide = transform.Find("UIGuide");
|
|
|
|
|
|
var system = transform.Find("UISystem");
|
|
|
|
|
|
if (backGround)
|
2025-04-08 14:54:25 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.BackGround, backGround.gameObject);
|
2025-04-08 14:54:25 +08:00
|
|
|
|
}
|
2025-12-19 11:54:18 +08:00
|
|
|
|
if (normal)
|
2025-04-08 14:54:25 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.Normal, normal.gameObject);
|
2025-04-08 14:54:25 +08:00
|
|
|
|
}
|
2025-12-19 11:54:18 +08:00
|
|
|
|
if (foreGround)
|
2025-04-08 14:54:25 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.ForeGround, foreGround.gameObject);
|
2025-04-08 14:54:25 +08:00
|
|
|
|
}
|
2025-12-19 11:54:18 +08:00
|
|
|
|
if (tips)
|
2025-04-08 14:54:25 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.Tips, tips.gameObject);
|
2025-04-08 14:54:25 +08:00
|
|
|
|
}
|
2025-12-19 11:54:18 +08:00
|
|
|
|
if (guide)
|
2025-04-08 14:54:25 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.Guide, guide.gameObject);
|
2025-04-08 14:54:25 +08:00
|
|
|
|
}
|
2025-12-19 11:54:18 +08:00
|
|
|
|
if (system)
|
2025-09-14 16:33:20 +08:00
|
|
|
|
{
|
2025-12-19 16:15:25 +08:00
|
|
|
|
_rootDic.Add(UICanvasLayer.System, system.gameObject);
|
2025-09-14 16:33:20 +08:00
|
|
|
|
}
|
2023-11-13 16:58:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-13 16:08:34 +08:00
|
|
|
|
// private void LateUpdate()
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (isDirty)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// isDirty = false;
|
|
|
|
|
|
// foreach (Text text in FindObjectsOfType<Text>())
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (text.font == dirtyFont)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// text.FontTextureChanged();
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// dirtyFont = null;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
2023-08-22 19:08:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Creates the window.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>The window.</returns>
|
|
|
|
|
|
/// <param name="windowName">UI预设名</param>
|
|
|
|
|
|
/// <param name="type">UI类型</param>
|
|
|
|
|
|
/// <param name="layer">UI层级</param>
|
2025-12-19 14:44:14 +08:00
|
|
|
|
public async UniTask<UIWindow> CreateWindow(string windowName, UICanvasLayer layer = UICanvasLayer.Normal)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
GameObject uiPrefab = await LoadPrefab(windowName);
|
2025-09-13 16:51:11 +08:00
|
|
|
|
if (uiPrefab is null)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
|
DebugUtil.LogError("{0}.CreateWindow, cannot find window resource : {1}", GetType(), windowName);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UIWindow window = null;
|
2025-12-19 16:15:25 +08:00
|
|
|
|
var root = _rootDic[layer];
|
2025-04-08 14:54:25 +08:00
|
|
|
|
GameObject obj = Instantiate(uiPrefab, root.transform, false) as GameObject;
|
2023-08-22 19:08:45 +08:00
|
|
|
|
string[] dirs = windowName.Split('/');
|
|
|
|
|
|
string className = dirs[dirs.Length - 1] + "Controller";
|
2024-01-26 16:06:42 +08:00
|
|
|
|
|
|
|
|
|
|
//window = obj.AddComponent(CommonUtilsFramework.GamePlayAssembly.GetType(className)) as UIWindow;
|
|
|
|
|
|
window = CommonUtilsFramework.GamePlayAssembly.CreateInstance(className) as UIWindow;
|
|
|
|
|
|
UIManager.BindWindowObj(window, obj);
|
|
|
|
|
|
|
2023-08-22 19:08:45 +08:00
|
|
|
|
if (window == null)
|
|
|
|
|
|
{
|
2023-10-19 15:00:19 +08:00
|
|
|
|
DebugUtil.LogError("Cant find UIWindow: {0}, check the name or remove any outter namespace.", className);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return window;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async UniTask<GameObject> LoadObj(string windowName)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameObject uiPrefab = null;
|
2025-06-30 16:08:02 +08:00
|
|
|
|
DebugUtil.Log($"LoadWindow:{windowName}");
|
2023-08-22 19:08:45 +08:00
|
|
|
|
var path = string.Format(UIManager.UI_PREFAB_PATH, windowName);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
uiPrefab = await AssetManager.Instance.LoadAssetAsync<GameObject>(path);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
return uiPrefab;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async UniTask<GameObject> LoadPrefab(string wName)
|
|
|
|
|
|
{
|
|
|
|
|
|
string windowName = wName;
|
|
|
|
|
|
GameObject uiPrefab = null;
|
|
|
|
|
|
// if (CommonUtils.IsLE_16_10())
|
|
|
|
|
|
// {
|
|
|
|
|
|
// uiPrefab = LoadObj(windowName + "_Pad");
|
|
|
|
|
|
// if (uiPrefab == null)// 增加一层兼容。如果ab包里加载不到,就去Resources目录里加载
|
|
|
|
|
|
// {
|
|
|
|
|
|
// uiPrefab = Resources.Load<GameObject>(Path.Combine("Loading",windowName + "_Pad"));
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
2025-09-13 16:51:11 +08:00
|
|
|
|
if (uiPrefab is null)
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
uiPrefab = await LoadObj(windowName);
|
2025-09-13 16:51:11 +08:00
|
|
|
|
if (uiPrefab is null) // 增加一层兼容。如果ab包里加载不到,就去Resources目录里加载
|
2023-08-22 19:08:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
uiPrefab = Resources.Load<GameObject>(Path.Combine("Loading",windowName));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return uiPrefab;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Vector2 GetScreenCanvasScale()
|
|
|
|
|
|
{
|
|
|
|
|
|
var rectTransform = Root.GetComponent<RectTransform>();
|
|
|
|
|
|
var screenSize = new Vector2(Screen.width, Screen.height);
|
2023-10-19 15:00:19 +08:00
|
|
|
|
var rect = rectTransform.rect;
|
|
|
|
|
|
return new Vector2(screenSize.x / rect.width, screenSize.y / rect.height);
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void EnableTouch(bool b)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cg = RootCanvas.GetComponent<CanvasGroup>();
|
|
|
|
|
|
cg.interactable = b;
|
|
|
|
|
|
cg.blocksRaycasts = b;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-03 14:07:54 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 是否激活射线检测
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="isEnable"></param>
|
|
|
|
|
|
public void IsEnableGraphicRaycaster(bool isEnable)
|
|
|
|
|
|
{
|
|
|
|
|
|
GraphicRaycaster graphicRaycaster = Root.GetComponent<GraphicRaycaster>();
|
2025-09-13 16:51:11 +08:00
|
|
|
|
if (graphicRaycaster is null)
|
2024-07-03 14:07:54 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
graphicRaycaster.enabled = isEnable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-06 14:44:11 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 新手引导是否激活射线检测(新手引导用)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="isEnable"></param>
|
|
|
|
|
|
public void IsEnableGraphicRaycasterByGuide(bool isEnable)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var kv in UIManager.Instance.mMemoryWindows)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (UINameConst.UIFightScene == kv.Key)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2024-10-29 16:51:09 +08:00
|
|
|
|
if (UINameConst.UINoticeOne == kv.Key)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (UINameConst.UINoticeTwo == kv.Key)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2025-09-14 12:37:38 +08:00
|
|
|
|
if (UINameConst.UI_GuideTip == kv.Key)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (UINameConst.UI_Guide == kv.Key)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2025-08-14 15:00:57 +08:00
|
|
|
|
kv.Value.GraphicRaycasterManager.IsEnableGraphicRaycaster = isEnable;
|
2024-09-06 14:44:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-07-19 13:12:50 +08:00
|
|
|
|
public void EnterUITopState()
|
|
|
|
|
|
{
|
|
|
|
|
|
UITopCamera.gameObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ExitUITopState()
|
|
|
|
|
|
{
|
2025-11-21 13:23:26 +08:00
|
|
|
|
//UITopCamera.gameObject.SetActive(false);
|
2024-07-19 13:12:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-19 19:42:30 +08:00
|
|
|
|
public void AddUI2UITopRoot(GameObject obj, bool isFirst = false)
|
2024-07-19 13:12:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (UITopRoot)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj.transform.SetParent(UITopRoot.transform);
|
2025-11-19 19:42:30 +08:00
|
|
|
|
if (isFirst)
|
|
|
|
|
|
obj.transform.SetAsFirstSibling();
|
2024-07-19 13:12:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-19 16:22:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-19 14:44:14 +08:00
|
|
|
|
/// 设置UI窗口的层级
|
2025-09-19 16:22:08 +08:00
|
|
|
|
/// </summary>
|
2025-12-19 14:44:14 +08:00
|
|
|
|
/// <param name="window">UI窗口</param>
|
|
|
|
|
|
/// <param name="layer">目标层级</param>
|
|
|
|
|
|
public void SetLayer(UIWindow window, UICanvasLayer layer)
|
2025-09-19 16:22:08 +08:00
|
|
|
|
{
|
2025-12-19 14:44:14 +08:00
|
|
|
|
if (window == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning("[UIRoot] UIWindow is null");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetLayer(window.gameObject, layer);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置UI对象的层级(用于非窗口UI元素,如血条、行动条等动态UI元素)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="go">UI对象</param>
|
|
|
|
|
|
/// <param name="layer">目标层级</param>
|
|
|
|
|
|
public void SetLayer(GameObject go, UICanvasLayer layer)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (go == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning("[UIRoot] GameObject is null");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 16:15:25 +08:00
|
|
|
|
if (!_rootDic.TryGetValue(layer, out GameObject goRoot))
|
2025-12-19 14:44:14 +08:00
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning($"[UIRoot] Cannot find canvas for layer: {layer}");
|
2025-09-19 16:22:08 +08:00
|
|
|
|
return;
|
2025-12-19 14:44:14 +08:00
|
|
|
|
}
|
2025-09-19 16:22:08 +08:00
|
|
|
|
|
2025-12-19 14:44:14 +08:00
|
|
|
|
go.transform.SetParent(goRoot.transform, false);
|
2025-09-19 16:22:08 +08:00
|
|
|
|
}
|
2025-12-19 16:15:25 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定层级的根节点
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="layer">UI层级</param>
|
|
|
|
|
|
/// <returns>对应的根节点GameObject,如果不存在返回null</returns>
|
|
|
|
|
|
public GameObject GetLayerRoot(UICanvasLayer layer)
|
|
|
|
|
|
{
|
|
|
|
|
|
return _rootDic.TryGetValue(layer, out var root) ? root : null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取所有根节点的只读字典(用于初始化等场景)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>只读的根节点字典</returns>
|
|
|
|
|
|
public IReadOnlyDictionary<UICanvasLayer, GameObject> GetAllLayerRoots()
|
|
|
|
|
|
{
|
|
|
|
|
|
return _rootDic;
|
|
|
|
|
|
}
|
2023-08-22 19:08:45 +08:00
|
|
|
|
}
|