/******************************************************************** 文件: UIManager.cs 作者: 梦语 邮箱: 1982614048@qq.com 创建时间: 2024/03/29 17:28:19 最后修改: 梦语 最后修改时间: 2024/04/03 15:10:11 功能: 界面管理类 *********************************************************************/ using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Accessibility; using UnityEngine.UI; namespace Ether { public class UIManager : SingletonAutoMono { [HideInInspector] public GameObject MainCanvas; //主画布 List tierList = new List(); //所有的层级 //所有打开的界面 private DictionaryEx allOpenFrames = new DictionaryEx(); //所有界面需要保存的数据 private DictionaryEx allFrameData = new DictionaryEx(); private LinkedSequence frameOpenStack = new LinkedSequence(); private LinkedSequence windowOpenStack = new LinkedSequence(); public override void Init() { Clear(); MainCanvas = EntityManager.Inst.GetEntity("MainCanvas").gameObject; CheckMainCanvasLayer(); } #region 层级管理 /// /// 检查MainCanvas下的层级 /// private void CheckMainCanvasLayer() { tierList.Clear(); //获取当前Canvas下所有的物体 int childNum = MainCanvas.transform.childCount; Transform[] childTrans = new Transform[childNum]; for (int i = 0; i < childNum; i++) { childTrans[i] = MainCanvas.transform.GetChild(i); } //动态创建UI层级 string[] frameLayers = CommonTools.GetAllEnumName(); foreach (string layer in frameLayers) { if (string.IsNullOrEmpty(layer)) { continue; } Transform trans = MainCanvas.transform.Find(layer); if (trans == null) { trans = new GameObject(layer, typeof(RectTransform)).transform; trans.SetParent(MainCanvas.transform, false); RectTransform rectTrans = trans.GetComponent(); rectTrans.anchorMin = new Vector2(0, 0); rectTrans.anchorMax = new Vector2(1, 1); rectTrans.anchoredPosition = Vector2.zero; rectTrans.sizeDelta = Vector2.zero; } tierList.Add(trans); trans.SetAsLastSibling(); } //设置Canvas下之前的物体层级到最上层 foreach (Transform trans in childTrans) { trans.SetAsLastSibling(); } } /// /// 获取层级 /// public Transform GetTier(int tierIndex) { if (tierList.Count <= tierIndex) { Debug.LogError($"没有该层级:{tierIndex},请检查配置"); return null; } return tierList[tierIndex]; } /// /// 获取层级 /// public Transform GetTier(FrameTier tier) { int tierIndex = (int)tier; if (tierList.Count <= tierIndex) { Debug.LogError($"没有该层级:{tier},请检查配置"); return null; } return tierList[tierIndex]; } #endregion /// /// 循环 /// private void Update() { float deltaTime = Time.deltaTime; foreach (var viewPair in allOpenFrames) { FrameBase frame = viewPair.Value; if (frame.IsActive) { frame.OnUpdate(deltaTime); } } } /// /// 打开界面 /// /// public void OpenFrame(string framName, FrameData openFrameData = null, Action callback = null) { Type frameType = CommonTools.GetType(framName); OpenFrame(framName, frameType, callback, openFrameData); } /// /// 打开界面 /// /// public void OpenFrame(FrameData openFrameData = null, Action callback = null) where T : FrameBase { string name = typeof(T).Name; OpenFrame(name, typeof(T), callback, openFrameData); } /// /// 打开界面 /// /// /// private void OpenFrame(string name, Type type, Action callback = null, FrameData openFrameData = null) { FrameBase frame; if (allOpenFrames.ContainsKey(name)) { frame = allOpenFrames[name]; frame.SetVisible(false); } else { frame = (FrameBase)Activator.CreateInstance(type); allOpenFrames.Add(name, frame); } if (openFrameData == null) { if (allFrameData.ContainsKey(name)) { openFrameData = allFrameData[name]; } } else { if (allFrameData.ContainsKey(name)) { allFrameData[name] = openFrameData; } else { allFrameData.Add(name, openFrameData); } } frame.SetVisible(true, callback, openFrameData); switch (frame.UIElement.frameType) { case FrameType.Frame: frameOpenStack.Add(name); string str = "当前打开的界面 :"; foreach (var node in frameOpenStack) { str += node.Value + " "; } Debug.Log(str); //全屏界面打开时关闭所有窗口界面 foreach (var node in windowOpenStack) { CloseFrame(node.Value); } break; case FrameType.Window: windowOpenStack.Add(name); string winStr = "当前打开的窗口 :"; foreach (var node in windowOpenStack) { winStr += node.Value + " "; } Debug.Log(winStr); break; case FrameType.Pop: break; default: break; } } /// /// 关闭界面 /// /// public void CloseFrame(Action callback = null) where T : FrameBase { string name = typeof(T).Name; CloseFrame(name, callback); } /// /// 关闭界面 /// /// public void CloseFrame(string frameName, Action callback = null) { if (allOpenFrames.ContainsKey(frameName)) { FrameBase frame = allOpenFrames[frameName]; frame.SetVisible(false, callback); allOpenFrames.Remove(frameName); } frameOpenStack.Remove(frameName); } /// /// 获取界面资源 /// /// /// /// public GameObject GetFrameRes(T frame) where T : FrameBase { Type viewType = typeof(T); UIElement element = frame.UIElement; if (element != null && !string.IsNullOrEmpty(element.prefabPath)) { GameObject obj = LoaderTools.LoadGameObjectAndInstantiateAsync(element.prefabPath, GetTier(element.tier)); if (obj == null) { Debug.LogErrorFormat("加载Frame Prefab失败:{0}!", element.prefabPath); return null; } obj.AddComponent(); obj.AddComponent(); obj.AddComponent(); return obj; } else { Debug.LogErrorFormat("当前Frame:{0}没有对应的Prefab路径,请添加入配置!", viewType); return null; } } /// /// 获取界面 /// public T GetFrame() where T : FrameBase { string name = typeof(T).Name; if (allOpenFrames.TryGetValue(name, out FrameBase frameBase)) { return frameBase as T; } return null; } /// /// 是否开启 /// public bool IsOpen() where T : FrameBase { return GetFrame() != null; } /// /// 窗口聚焦 /// public void FocusWindow(string name) { var node = windowOpenStack[name]; node.SetAsLastSibling(); } /// /// 返回 /// public void BackFrame(string name, FrameType frameType) { switch (frameType) { case FrameType.Frame: frameOpenStack.Remove(name); if (frameOpenStack.Count > 0) { OpenFrame(frameOpenStack.Last().Value); } break; case FrameType.Window: frameOpenStack.Remove(name); break; case FrameType.Pop: break; default: break; } } /// /// 清理 /// public override void Clear() { tierList.Clear(); frameOpenStack.Clear(); windowOpenStack.Clear(); foreach (var frameNodePair in allOpenFrames) { frameNodePair.Value.Close(); } } } }