123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using UnityEngine;
- namespace TFramework
- {
- [DefaultExecutionOrder(-9999)]
- public class UIManager : BaseManager
- {
- private Stack<BasePanel> panelStack;
- private Dictionary<string, BasePanel> panelDict;
- private List<BasePanel> panelBuffer;
- private Dictionary<string, Transform> _worldUIDomain;
- private TAction<BasePanel, BasePanel> OnPanelChanged;
- private BasePanel _currentPanel;
- /// <summary>
- /// 当前打开的面板
- /// </summary>
- public BasePanel CurrentPanel
- {
- get => _currentPanel;
- private set
- {
- OnPanelChanged?.Invoke(_currentPanel, value);
- _currentPanel = value;
- }
- }
- public const string DEFAULTDOMAIN = "默认UI域";
- public void Awake()
- {
- panelStack = new Stack<BasePanel>();
- panelDict = new Dictionary<string, BasePanel>();
- panelBuffer = new List<BasePanel>();
- _worldUIDomain = new Dictionary<string, Transform>();
- }
- /// <summary>
- /// 注册UI作用域 (即父物体)
- /// </summary>
- /// <param name="name">名字</param>
- /// <param name="domain">作用域</param>
- 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作用域");
- }
- /// <summary>
- /// 打开UI
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public T OpenUI<T>(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;
- }
- /// <summary>
- /// 预加载UI 加载完成不打开
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void PreopenUI<T>() => PreopenUI(typeof(T));
- /// <summary>
- /// 预加载UI 加载完成不打开
- /// </summary>
- /// <typeparam name="Type"></typeparam>
- public void PreopenUI(Type type)
- {
- BasePanel panel = GetPanel(type);
- if (panel != null)
- panel.UIEntity.SetActive(false);
- }
- /// <summary>
- /// 置顶UI
- /// </summary>
- private void StickyTopic()
- {
- foreach (var item in panelDict.Values)
- if (item.UIEntity!=null && item.UIEntity.activeSelf && item.StickyTopic)
- item.UIEntity.transform.SetAsLastSibling();
- }
- /// <summary>
- /// 关闭UI
- /// </summary>
- 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);
- }
- /// <summary>
- /// 关闭UI
- /// </summary>
- /// <param name="type">UI类型</param>
- /// <param name="isDestroy">是否销毁</param>
- /// <param name="args">参数</param>
- public void CloseUI<T>(bool isDestroy = false, IPanelData args=null) => CloseUI(typeof(T), isDestroy, args);
- /// <summary>
- /// 关闭UI
- /// </summary>
- /// <param name="type">UI类型</param>
- /// <param name="isDestroy">是否销毁</param>
- /// <param name="args">参数</param>
- 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);
- }
- }
- /// <summary>
- /// 获取面板
- /// </summary>
- /// <param name="type"></param>
- /// <returns></returns>
- private BasePanel GetPanel(Type type)
- {
- UIResourceAttribute attribute = type.GetCustomAttribute<UIResourceAttribute>();
- BasePanel panel = panelDict.TryGet(type.FullName);
- if (panel == null)
- {
- panel = Activator.CreateInstance(type) as BasePanel;
- GameObject game = Main.GetMagr<ResourceManager>().LoadAsset(new LoadResHandle<GameObject>(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;
- }
- /// <summary>
- /// 获取已创建的面板
- /// </summary>
- /// <returns></returns>
- public T GetAlreadyHavePanel<T>() where T : BasePanel => panelDict.TryGet(typeof(T).FullName) as T;
- /// <summary>
- /// 获取已创建的面板
- /// </summary>
- /// <returns></returns>
- public BasePanel GetAlreadyHavePanel(string typeFullName) => panelDict.TryGet(typeFullName);
- /// <summary>
- /// 关闭指定UIPanel
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public void CloseUI<T>(IPanelData args) where T : BasePanel => CloseUI<T>(false, args);
- public void AddPanelChanged(TAction<BasePanel, BasePanel> action) => OnPanelChanged += action;
- public void RemovePanelChanged(TAction<BasePanel, BasePanel> action) => OnPanelChanged -= action;
- /// <summary>
- /// 切换语言
- /// </summary>
- internal void ChangedWord()
- {
- foreach (var item in panelDict.Values)
- {
- item.ChangedWord();
- }
- }
- }
- }
|