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);
}
}
}