using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using UnityEngine; namespace TFramework { [DefaultExecutionOrder(-9999)] public class UIManager : BaseManager { private Stack panelStack; private Dictionary panelDict; private List panelBuffer; private Dictionary _worldUIDomain; private TAction OnPanelChanged; private BasePanel _currentPanel; /// /// 当前打开的面板 /// public BasePanel CurrentPanel { get => _currentPanel; private set { OnPanelChanged?.Invoke(_currentPanel, value); _currentPanel = value; } } public const string DEFAULTDOMAIN = "默认UI域"; public void Awake() { panelStack = new Stack(); panelDict = new Dictionary(); panelBuffer = new List(); _worldUIDomain = new Dictionary(); } /// /// 注册UI作用域 (即父物体) /// /// 名字 /// 作用域 public void RegisterUIDomain(string name, Transform domain) { if (_worldUIDomain.ContainsKey(name)) Log.Error($"UI作用域名称【{name}】被重复注册"); else _worldUIDomain.Add(name, domain); } public void UnregisterUIDomain(string name) { if (_worldUIDomain.ContainsKey(name)) _worldUIDomain.Remove(name); else Log.Error($"不存在名为【{name}】的UI作用域"); } /// /// 打开UI /// /// public T OpenUI(IPanelData args = null) where T : BasePanel => OpenUI(typeof(T), args) as T; public BasePanel OpenUI(Type type, IPanelData args = null) { if (panelStack.Count > 0) panelStack.Peek().OnPause(args); BasePanel panel = GetPanel(type); if (panel == null) return null; panel.UIEntity.SetActive(true); CurrentPanel = panel; panel.UIEntity.transform.SetAsLastSibling(); panelStack.Push(panel); panel.OnEnter(args); StickyTopic(); return panel; } /// /// 预加载UI 加载完成不打开 /// /// public void PreopenUI() => PreopenUI(typeof(T)); /// /// 预加载UI 加载完成不打开 /// /// public void PreopenUI(Type type) { BasePanel panel = GetPanel(type); if (panel != null) panel.UIEntity.SetActive(false); } /// /// 置顶UI /// private void StickyTopic() { foreach (var item in panelDict.Values) if (item.UIEntity!=null && item.UIEntity.activeSelf && item.StickyTopic) item.UIEntity.transform.SetAsLastSibling(); } /// /// 关闭UI /// public void CloseUI(IPanelData args=null) { if (panelStack.Count <= 0) return; BasePanel toPanel = panelStack.Pop(); if (toPanel.UIEntity == null) return; toPanel.UIEntity.SetActive(false); toPanel.OnExit(args); if (panelStack.Count <= 0) return; CurrentPanel = panelStack.Peek(); CurrentPanel.OnResume(args); } /// /// 关闭UI /// /// UI类型 /// 是否销毁 /// 参数 public void CloseUI(bool isDestroy = false, IPanelData args=null) => CloseUI(typeof(T), isDestroy, args); /// /// 关闭UI /// /// UI类型 /// 是否销毁 /// 参数 public void CloseUI(Type type, bool isDestroy = false, IPanelData args=null) { BasePanel panel = GetAlreadyHavePanel(type.FullName); if (panel == null) return; if (panelStack.Peek() == panel) CloseUI(args); else { panelBuffer.Clear(); if (panel.UIEntity.activeSelf) { while (panelStack.Peek() != panel) panelBuffer.Add(panelStack.Pop()); BasePanel toPanel = panelStack.Pop(); if(toPanel.UIEntity!=null) { toPanel.UIEntity.SetActive(false); toPanel.OnExit(args); } for (int i = panelBuffer.Count - 1; i >= 0; i--) panelStack.Push(panelBuffer[i]); } } if (isDestroy) { GameObject.DestroyImmediate(panel.UIEntity); panelDict.Remove(type.FullName); } } /// /// 获取面板 /// /// /// private BasePanel GetPanel(Type type) { UIResourceAttribute attribute = type.GetCustomAttribute(); BasePanel panel = panelDict.TryGet(type.FullName); if (panel == null) { panel = Activator.CreateInstance(type) as BasePanel; GameObject game = Main.GetMagr().LoadAsset(new LoadResHandle(attribute)); if(game==null) { Log.Error($"未加载到【{type}】UI实体,请检查实体路径是否正确!"); return panel; } panel.UIEntity = Instantiate(game); if (!string.IsNullOrEmpty(attribute.WorlUIDomain)) { if (!_worldUIDomain.ContainsKey(attribute.WorlUIDomain)) Log.Error($"UI【{game.name}】执行文件【{type.Name}】的作用域未注册,请确定其作用域对象挂载了【WorldUIDomain】脚本!"); else panel.UIEntity.transform.SetParent(_worldUIDomain[attribute.WorlUIDomain], false); } panel.OnInit(); panel.ChangedWord(); panelDict.Add(type.FullName, panel); } return panel; } /// /// 获取已创建的面板 /// /// public T GetAlreadyHavePanel() where T : BasePanel => panelDict.TryGet(typeof(T).FullName) as T; /// /// 获取已创建的面板 /// /// public BasePanel GetAlreadyHavePanel(string typeFullName) => panelDict.TryGet(typeFullName); /// /// 关闭指定UIPanel /// /// public void CloseUI(IPanelData args) where T : BasePanel => CloseUI(false, args); public void AddPanelChanged(TAction action) => OnPanelChanged += action; public void RemovePanelChanged(TAction action) => OnPanelChanged -= action; /// /// 切换语言 /// internal void ChangedWord() { foreach (var item in panelDict.Values) { item.ChangedWord(); } } } }