using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; //using UnityEditor; using Game; using Axibug.Resources; using Axibug.Runtime; using UnityEngine.Events; using Axibug; using UnityEditor; using Game; public enum eUINodeType { NodeBg = 0, // 游戏根层显示, 主要用来显示背景贴图 NodeScreen, // 全屏UI, 比如主场景的主UI, 战斗场景战斗UI. NodeUI, // 功能UI等 NodeLoading, // 加载界面层 NodeTip, // 提示层 } /// /// 为了兼容异步加载的问题定义的数据结构 /// public class CustomUserData { public UIBase ui; public Type mType; public string uiName; public Transform tfParent; public AssetBundle descBundle; public object[] userData; } /// /// UIManager /// UI管理器 /// 常用方法: /// UIMgr.Instance.Open() 显示某个UI /// UIMgr.Instance.OpenInChild() 在某个结点下显示UI /// UIMgr.Instance.GetUI() 获取某个打开的UI实例 /// UIMgr.Instance.GetTopUI() 获取最外层UI /// UIMgr.Instance.Hide() 隐藏某个UI /// UIMgr.Instance.HideAll() 隐藏所有UI /// UIMgr.Instance.CloseUI() 销毁某个UI /// UIMgr.Instance.CloseUI(UIBase _ui) 销毁某个UI /// UIMgr.Instance.Clean() 销毁所有UI /// UIMgr.Instance.CleanExceptLoading() 销毁除LoadingUI外的所有UI /// UIMgr.Instance.MoveRootUp() 移动UI上下位置 /// public class UIMgr : GameComponent { public static UIMgr Instance; public static readonly string UIPrefabRootPath = "Assets/GameAssets/Prefabs/UI"; // UI Prefab根目录 //public static readonly string UIPathConfigFile = "Assets/GameAssets/TextAssets/UIMgrPath.asset"; // UI Prefab资源路径文件名 public static readonly string UIPathConfigFile = "Assets/GameAssets/TextAssets/UIMgrPath.json"; // UI Prefab资源路径文件名 public static readonly string UIMainHubSubConfigFile = "Assets/GameAssets/TextAssets/UIMainHubSubConfig.asset"; //主UI的子UI预制体名 public Transform m_NodeBg; // 背景层 public Transform m_NodeScreen; // 全屏UI层, 比如主场景的主UI, 战斗场景战斗UI. 人物信息, 血条, 主界面的小地图等等 public Transform m_NodeUI; // UI层, 功能层. 比如强化, 宠物等 public Transform m_NodeLoading; // 加载界面层 public Transform m_NodeTip; // 弹窗提示层 public RectTransform m_RtfShelter; // 遮挡 用于4:3屏幕适配 private Transform m_NodeUITop; // UI顶层 private static UIBase mTopUI; // 当前最外层UI private static Dictionary m_UIDic; public static Dictionary UIDic { get { if (m_UIDic == null) m_UIDic = new Dictionary(); return m_UIDic; } } // 同步方式 保留 private static Dictionary m_AllUIPath; public static Dictionary AllUIPath { get { if (m_AllUIPath == null) { m_AllUIPath = new Dictionary(); m_AllUIPath = UIMgrPath.GetDic(); } return m_AllUIPath; } } public static Dictionary m_TypeParent; private RawImage m_imgBg; public Camera m_camera; private bool m_isScreenClip; // 屏幕是否用黑边裁剪了 public bool IsScreenClip { get { return m_isScreenClip; } set { m_isScreenClip = true; } } public Type hotResources = null; protected override void Awake() { base.Awake(); Instance = this; //DontDestroyOnLoad(this); m_camera = transform.Find("Camera").GetComponent(); m_NodeBg = transform.Find("Canvas/NodeBg"); m_NodeScreen = transform.Find("Canvas/NodeScreen"); m_NodeUI = transform.Find("Canvas/NodeUI"); m_NodeLoading = transform.Find("Canvas/NodeLoading"); m_NodeTip = transform.Find("Canvas/NodeTip"); m_RtfShelter = transform.Find("Canvas/RtfShelter").GetComponent(); m_TypeParent = new Dictionary { {eUINodeType.NodeBg, m_NodeBg }, {eUINodeType.NodeScreen, m_NodeScreen }, {eUINodeType.NodeUI, m_NodeUI }, {eUINodeType.NodeTip, m_NodeTip }, {eUINodeType.NodeLoading, m_NodeLoading }, }; m_NodeUITop = m_NodeUI.Find("Top"); m_imgBg = m_NodeBg.Find("imgBg").GetComponent(); } private void OnEnable() { Inform.Listen(eInformId.SenceChange, CleanExceptLoading); } private void OnDisable() { Inform.Cancel(eInformId.SenceChange, CleanExceptLoading); } public T LoadAsset(string assetName) where T : UnityEngine.Object { if (AppEntry.Base.EditorResourceMode) { #if UNITY_EDITOR T asset = AssetDatabase.LoadAssetAtPath(assetName); return asset; #endif } string rootPath = "Assets/GameAssets"; string tmp = assetName.Remove(0, rootPath.Length + 1); int idx = tmp.LastIndexOf('/'); string bundleName = tmp.Substring(0, idx); int id = assetName.GetHashCode(); return PrefabManager.LoadPrefab(bundleName.ToLower(), assetName, id, null); } public GameObject Clone(string assetName, Transform parent = null) { string rootPath = "Assets/GameAssets"; string tmp = assetName.Remove(0, rootPath.Length + 1); int idx = tmp.LastIndexOf('/'); string bundleName = tmp.Substring(0, idx); //if (bundleName.Contains("Login/")) //{ // idx = bundleName.LastIndexOf('/'); // bundleName = bundleName.Substring(0, idx); //} UnityEngine.Object asset = null; if (AppEntry.Base.EditorResourceMode) { #if UNITY_EDITOR asset = AssetDatabase.LoadAssetAtPath(assetName); #endif } else { int id = assetName.GetHashCode(); asset = PrefabManager.LoadPrefab(bundleName.ToLower(), assetName, id, parent); } if (asset == null) { Debug.LogError($"asset加载失败,path={assetName}"); return null; } GameObject go = Instantiate(asset, parent) as GameObject; if (go == null) { Debug.LogError("LoadPrefabByEditor2. go == null. asset:" + asset); } return go; } public UIBase OpenUI(eUINodeType _layer = eUINodeType.NodeUI, params object[] _params) where T : UIBase { Transform _tfParent = m_TypeParent[_layer]; return OpenUIInChild(_tfParent, _params); //return OpenUIInChild(_layer, _params); } public UIBase OpenUIInChild(Transform _tfParent = null , params object[] _params) where T:UIBase { Type vT = typeof(T); string uiName = vT.Name; return OpenUIInChild(uiName, _tfParent, vT, _params) as T; } public UIBase OpenUIInChild(string _uiName, Transform _tfParent = null, Type _typeOfT = null, params object[] _params) { string uiName = _uiName; if (!AllUIPath.ContainsKey(uiName)) { Debug.LogError("OpenUIInChild. not found UIPath. uiName:" + uiName); return null; } var uiPath = AllUIPath[uiName]; if (string.IsNullOrEmpty(uiPath)) { Debug.LogError("OpenUIInChild. string.IsNullOrEmpty(uiPath). uiName:" + uiName); return null; } if(_tfParent == null) _tfParent = m_TypeParent[eUINodeType.NodeUI]; // 如果已经有缓存的了 则直接激活换成缓存里的 if (UIDic.ContainsKey(uiName)) { var uiScript = UIDic[uiName]; uiScript.gameObject.SetActive(true); uiScript.transform.SetParent(_tfParent); UIMoveTop(uiScript); uiScript.Show(_params); return uiScript; } Log.Debug($"uipath = {uiPath}"); GameObject uiObj = Clone(uiPath, _tfParent); uiObj.name = uiName; UIBase uiBase = uiObj.GetComponent(); if (uiBase == null) { uiBase = uiObj.AddComponent(_typeOfT) as UIBase; } UIDic.Add(uiName, uiBase); UIMoveTop(uiBase); uiBase.Show(_params); return uiBase; } /// /// 跳转UI, 请用Common.SkipToUI 来跳转UI /// /// //public UIBase SkipToUI(int _funcCid, int _funcSubCid = 0) private void UIMoveTop(UIBase uiScript) { mTopUI = uiScript; MoveRootUp(uiScript.transform, m_NodeUITop); MoveRootUp(m_NodeUITop, uiScript.transform); } /// /// 关闭UI 建议在UI内直接调用CloseUI(this) /// public void CloseUI(string _uiName) { var strNameAry = _uiName.Split('.'); _uiName = strNameAry[strNameAry.Length - 1]; if (!UIDic.ContainsKey(_uiName)) { Debug.LogError("缓存中 没找到该UI _uiName:" + _uiName); return; } //这里改一下,直接删除ab包 if (!AllUIPath.ContainsKey(_uiName)) { Debug.LogError("CloseUI. not found UIPath. uiName:" + _uiName); return ; } var uiPath = AllUIPath[_uiName]; string rootPath = "Assets/GameAssets"; string tmp = uiPath.Remove(0, rootPath.Length + 1); int idx = tmp.LastIndexOf('/'); string bundleName = tmp.Substring(0, idx); Hide(_uiName); if(!AppEntry.Base.EditorResourceMode) AssetBundleManager.UnLoad(bundleName.ToLower()); GameObject.Destroy(UIDic[_uiName].gameObject); if (UIDic.ContainsKey(_uiName)) UIDic.Remove(_uiName); } /// /// 关闭UI /// public void CloseUI() where T : UIBase { string uiName = typeof(T).Name; CloseUI(uiName); } /// /// 关闭UI 建议在UI内直接调用CloseUI(this) /// /// 界面实力 public void CloseUI(UIBase _ui) { if (_ui == null) { Debug.LogError("CloseUI, _ui == null."); return; } Type _t = _ui.GetType(); string uiName = _t.Name; CloseUI(uiName); } public void CloseAll() { List needCloseUIName = new List(); foreach (KeyValuePair Pair in UIDic) { needCloseUIName.Add(Pair.Key); } UIDic.Clear(); HideBg(); } public void CloseAllUI() { List tCloseList = new List(); foreach (var ui in UIDic.Values) { tCloseList.Add(ui); } foreach (var ui in tCloseList) { CloseUI(ui); } } public void Hide(UIBase _ui) { if (_ui == null) { Debug.LogError("CloseUI, _ui == null."); return; } Type _t = _ui.GetType(); string uiName = _t.Name; Hide(uiName); } public void Hide() where T : UIBase { string uiName = typeof(T).Name; Hide(uiName); } public void Hide(string uiName) { if (!UIDic.ContainsKey(uiName)) { Debug.LogError("缓存中 没找到该UI uiName:" + uiName); return; } var ui = UIDic[uiName]; if (ui == null) { UIDic.Remove(uiName); return; } ui.gameObject.SetActive(false); if (ui == mTopUI) mTopUI = null; } public void HideAll() { foreach (KeyValuePair Pair in UIDic) { Hide(Pair.Key); } } /// /// 判断某个界面是否已经打开 /// public bool IsOpen() where T : UIBase { string uiName = typeof(T).Name; return IsOpen(uiName); } public bool IsOpen(string uiName) { if (!UIDic.ContainsKey(uiName)) { //Debug.LogError("缓存中 没找到该UI uiName:" + uiName); return false; } var ui = UIDic[uiName]; if (ui == null) { UIDic.Remove(uiName); return false; } return ui.gameObject.activeSelf; } /// /// 获取打开的某个界面 /// /// /// null:没有打开 public T GetUI() where T : UIBase { string uiName = typeof(T).Name; return GetUI(uiName) as T; } /// /// 获取UI /// /// /// public UIBase GetUI(string _uiName) { if (UIDic.ContainsKey(_uiName)) { return UIDic[_uiName]; } Debug.Log("GetUI. return null. _uiName:" + _uiName); return null; } /// /// 获取最顶层的UI /// /// null:没有打开的UI public UIBase GetTopUI() { if (mTopUI != null) return mTopUI; int maxSiblingIdx = -9999; foreach (var ui in UIDic.Values) { if (ui == null) continue; int siblingIdx = ui.transform.GetSiblingIndex(); if (siblingIdx <= maxSiblingIdx) continue; mTopUI = ui; maxSiblingIdx = siblingIdx; } if (mTopUI == null) { // 获取最外层 Debug.Log("GetTopUI. mTopUI == null. 当前没有打开的UI"); } return mTopUI; } public void HideBg() { if (m_imgBg.gameObject.activeSelf) m_imgBg.gameObject.SetActive(false); } public void Clean() { foreach (KeyValuePair Pair in UIDic) { if (Pair.Value.gameObject != null) GameObject.Destroy(Pair.Value.gameObject); } UIDic.Clear(); HideBg(); } // 清理除Loading以外的UI public void CleanExceptLoading() { List exceptUIList = new List() { "LoadingUI" }; CleanExceptList(exceptUIList); } // 清理除传入列表相关UI public void CleanExceptList(List _uiNameList = null) { if (_uiNameList == null || _uiNameList.Count <= 0) { Clean(); return; } List needRemoveKeyLst = new List(); foreach (KeyValuePair Pair in UIDic) { if (Pair.Value.transform.parent == m_NodeLoading) continue; if (Pair.Value.gameObject != null) { if (_uiNameList.Contains(Pair.Key)) continue; needRemoveKeyLst.Add(Pair.Key); } } for (int i = 0; i < needRemoveKeyLst.Count; i++) { CloseUI(needRemoveKeyLst[i]); } needRemoveKeyLst.Clear(); HideBg(); } public void CloseCamera() { m_camera.gameObject.SetActive(false); } public void ShowCamera() { if (m_camera) m_camera.gameObject.SetActive(true); } /// /// 把一个UI的Transform _Tf1 移到 另一个UI的Transform _Tf2 上面 /// public void MoveRootUp(Transform _Tf1, Transform _Tf2) { _Tf1.SetSiblingIndex(_Tf2.GetSiblingIndex() + 1); } /// /// 改变UI透明度, 先不对外开放功能 /// /// /// private void ChangeAlpha(Transform _tf, float _alpha) { // 是否有必要改成canvasGroup Image[] imageAry = _tf.GetComponentsInChildren(); for (int i = 0; i < imageAry.Length; i++) { Color old = imageAry[i].color; imageAry[i].color = new Color(old.r, old.g, old.b, _alpha); } Text[] textAry = _tf.GetComponentsInChildren(); for (int i = 0; i < textAry.Length; i++) { Color old = textAry[i].color; textAry[i].color = new Color(old.r, old.g, old.b, _alpha); } } }