/*
*实现“缓存”“自动加载”“层级管理”的设计功能
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SUIFW
{
public class UIManager : MonoBehaviour
{
#region 定义变量
//三个重要字典
//路径、所有窗体、当前显示窗体
private Dictionary<string, string> _DicUIFormPaths; //路径字典(通过窗体名获取路径)
private Dictionary<string, BaseUIForm> _DicAllUIForms; //所有窗体字典(缓存所有UI窗体)
private Dictionary<string, BaseUIForm> _DicCurrentShowUIForms;//当前显示窗体 字典 集合
private Stack<BaseUIForm> _StaCurrentShowUIForms; //当前显示窗体 栈 集合
//得到挂载节点
private Transform traCanvas;
private Transform traNormal;
private Transform traFixed;
private Transform traPopup;
private Transform traUIScript;
#endregion
#region 设为单例类
private static UIManager _Instance;
public static UIManager GetInstance()
{
if(_Instance==null)
{
_Instance = new GameObject("_UIManager").AddComponent<UIManager>();
}
return _Instance;
}
#endregion
void Awake()//最重要的任务是,把Canvas预设体,挂到层级视图上,然后让它DontDestroyOnLoad(1)。初始化字典(2)、找到各节点并把此脚本所在的_UIManager物体放到_ScriptMgr节点下都是次要的,其中“各节点”指Canvas画布中的Normal、Fixed、Pop、_ScriptMgr(3),初始化窗体路径字典集合(4)
{ //(1)
//GameObject myCanvas=ResourcesMgr.GetInstance().LoadAsset("Canvas",true);
GameObject myCanvas = ResourcesMgr.GetInstance().LoadAsset(SystemDefine.SYS_Canvas_Path, false);
DontDestroyOnLoad(myCanvas);
//(2)
_DicUIFormPaths = new Dictionary<string, string>(); //窗体名|路径(窗体预设体在Resources文件夹下的)
_DicAllUIForms = new Dictionary<string, BaseUIForm>(); //窗体名|窗体类 (每个窗体预设体都挂有一个继承自BaseUIForm、和窗体同名的类)
_DicCurrentShowUIForms = new Dictionary<string, BaseUIForm>(); //窗体名|窗体类
_StaCurrentShowUIForms = new Stack<BaseUIForm>();
//(3)
traCanvas = GameObject.Find("Canvas(Clone)").transform;
traNormal = traCanvas.Find(SystemDefine.SYS_NormalNodeName);
traFixed = traCanvas.Find(SystemDefine.SYS_FixedNodeName);
traPopup = traCanvas.Find(SystemDefine.SYS_PopupNodeName);
traUIScript = traCanvas.Find(SystemDefine.SYS_ScriptMgrNodeName);
transform.SetParent(traUIScript);
//(4)
if (_DicUIFormPaths != null)
{
//_DicUIFormPaths.Add("LogonUIForm", "UIPrefabs/LogonUIForm");
//_DicUIFormPaths.Add("SelectHeroUIForm", "UIPrefabs/SelectHeroUIForm");
//_DicUIFormPaths.Add("MainCityUIForm", "UIPrefabs/MainCityUIForm");
//_DicUIFormPaths.Add("HeroInfoUIForm", "UIPrefabs/HeroInfoUIForm");
//_DicUIFormPaths=ConfigManagerByJson("Json/UIFormsConfigInfo");
//ConfigManagerByJson configManagerByJsonObj = new ConfigManagerByJson("UIFormsConfigInfo");
//_DicUIFormPaths = configManagerByJsonObj.AppSetting;
//路径字典集合,Json数据载入
Init_DicUIFormPaths_Data();
}
//transform.localScale = Vector3.one;
}
#region 打开窗体 系列方法
/// <summary>
/// 打开窗体方法
/// </summary>
/// <param name="uiFormName"></param>
public void ShowUIForm(string uiFormName)//首要任务,把窗体预设体载入(1)、挂好(2)(顺便将其先隐藏(3),加入所有窗体缓存集合(4))其次,根据窗体显示模式,进行不同的操作(5)
{
BaseUIForm wanttedUIForm = null;
//参数检查,看窗体的名字是否为空
if (string.IsNullOrEmpty(uiFormName))
{
Debug.Log("名字为空");
return;
}
wanttedUIForm = LoadUIFormToAllFormsCache(uiFormName);
if (wanttedUIForm == null) return;
//如果UIType脚本中,IsClearStack为true,说明要进行清空栈操作
if (wanttedUIForm.CurrentUIType.IsClearStack == true)
{
ClearStackArray();
}
//(5)
switch (wanttedUIForm.GetComponent<BaseUIForm>().CurrentUIType.UIForm_ShowMode)
{
case UIFormShowMode.Normal:
//wanttedUIForm.gameObject.SetActive(true);
LoadUIFormToCurrentShowUIForm(uiFormName);
break;
case UIFormShowMode.ReverseChange:
PushWanttedFormToStack(uiFormName);
break;
case UIFormShowMode.HideOther:
ShowUIForm_HideOther(uiFormName);
break;
}
}
/// <summary>
/// 从缓存集合里得到窗体——即如果缓存集合中有此窗体直接返回,没有就去加载
/// </summary>
/// <param name="uiFormName"></param>
/// <returns></returns>
public BaseUIForm LoadUIFormToAllFormsCache(string uiFormName)//加载完第一遍后,它不用时就隐藏——需要加载第二遍时,直接从所有缓存集合中取,不需要重新加载了
{
BaseUIForm tempUIForm = null;
_DicAllUIForms.TryGetValue(uiFormName, out tempUIForm);
if(tempUIForm==null)
{
tempUIForm = LoadUIForm(uiFormName);
}
return tempUIForm;
}
/// <summary>
/// 纯加载
/// </summary>
/// <param name="uiFormName"></param>
/// <returns></returns>
///
public BaseUIForm LoadUIForm(string uiFormName)
{
//由窗体名字的得到路径,通过路径载入窗体(1);其次,根据窗体的位置信息,把它挂好(2)(顺便把新窗体隐掉(3),加入“所有UI窗体缓存集合”(4))。
BaseUIForm tempUIForm=null;
string uiFormPath = null;
GameObject prefabClone = null;
//(1)
_DicUIFormPaths.TryGetValue(uiFormName, out uiFormPath);
if (!string.IsNullOrEmpty(uiFormPath))
{
prefabClone = ResourcesMgr.GetInstance().LoadAsset(uiFormPath, false);
if(prefabClone!=null)
#region //载入,及可能的异常
{
tempUIForm = prefabClone.GetComponent<BaseUIForm>();//动态多态性,得到的是具体的窗体类
if(tempUIForm)
{//(2)
switch (tempUIForm.CurrentUIType.UIForm_Pos)
{
case UIFormPos.Normal:
tempUIForm.transform.SetParent(traNormal,true);
break;
case UIFormPos.Fixed:
tempUIForm.transform.SetParent(traFixed,true);
break;
case UIFormPos.Popup:
tempUIForm.transform.SetParent(traPopup,true);
break;
}
//(3)
tempUIForm.gameObject.SetActive(false);
//(4)
_DicAllUIForms.Add(uiFormName, tempUIForm);
}
else
{
Debug.Log("克隆体的原物体上,未挂脚本。克隆体的名称是:"+prefabClone.name);
}
}
else
{
Debug.Log("在该位置找不到预设体");//路径字符串错了,或正确字符串下没放预设体
}
#endregion
}
else
{
Debug.Log("路径缓存集合中,此名字的路径不存在");//窗体名字写错了,或者正确名字下,Json中路径Value是空的。
}
return tempUIForm;
}
/// <summary>
/// 添加到“_DicCurrentShowUIForm”集合 (窗体类是从“_DicAllUIForms”中获取的)(并让窗体显示),事先 检查“当前显示UIForm集合”是否初始化,进一步检查“当前显示UIForm集合”是否有它(另检查<所有UI窗体集合>中是否有该窗体类)
/// </summary>
/// <param name="uiFormName"></param>
public void LoadUIFormToCurrentShowUIForm(string uiFormName)
{
//我自己写的
//BaseUIForm tempUIForm=null;
//if(_DicCurrentShowUIForm!=null)
//{
// BaseUIForm tempUIForm1 = null;
// if( _DicCurrentShowUIForm.TryGetValue(uiFormName,out tempUIForm1))
// {
// Debug.Log("<当前显示窗体>集合中已经有该元素,不需要重新添加");
// return;
// }
// if (_DicAllUIForms.TryGetValue(uiFormName, out tempUIForm))
// {
// _DicCurrentShowUIForm.Add(uiFormName, tempUIForm);
// }
// else
// {
// Debug.Log("<所有UI窗体>集合中没有这个窗体类");
// }
//}
//else
//{
// Debug.Log("<当前显示窗体集合>不存在或者没有初始化");
//}
//原先简化的
if (_DicCurrentShowUIForms == null)
{
Debug.Log("_DicCurrentShowUIForm没有初始化");
return;
}
BaseUIForm baseUIForm = null;
if (_DicCurrentShowUIForms.TryGetValue(uiFormName, out baseUIForm))
{
Debug.Log("_DicCurrentShowUIForm已经添加了此窗体类");
// baseUIForm.Display();
return;
}
BaseUIForm tempUIForm = null;
if (!_DicAllUIForms.TryGetValue(uiFormName, out tempUIForm))
{
Debug.Log("_DicAllUIForms不存在这个窗体类");
return;
}
tempUIForm.Display();
_DicCurrentShowUIForms.Add(uiFormName, tempUIForm);
}
/// <summary>
/// 窗体入栈 事先冻结栈中窗体的栈顶元素窗体(1),从“_DicAllUIForms”找到要显示的UI窗体后,把它加入当前显示栈中,并显示(2)——不需要加入当前显示缓存集合吗?
/// </summary>
/// <param name="uiFormName"></param>
public void PushWanttedFormToStack(string uiFormName)
{
if(_StaCurrentShowUIForms.Count>1)
{
BaseUIForm topFormClassInStack= _StaCurrentShowUIForms.Peek();
topFormClassInStack.Freeze();//里面的秒表计数器等等,都停止?
}
BaseUIForm newUIForm = null;
if(_DicAllUIForms.TryGetValue(uiFormName,out newUIForm))
{
_StaCurrentShowUIForms.Push(newUIForm);
newUIForm.Display();
}
else
{
Debug.Log("所有窗体集合中,找不到这个类");
}
}
/// <summary>
/// 隐藏其它窗体的打开:把普通窗体_DicCurrentShowUIForm集合、反向切换窗体_StaCurrentShowUIForm,这两个集合中的窗体统统关闭——然后,把要显示的窗体放到_DicCurrentShowUIForm集合中+显示(2),事先检查该窗体是否已经显示过了,已显示就不再往当前显示集合_DicCurrentShowUIForm里放了(1)
/// </summary>
public void ShowUIForm_HideOther(string uiFormName)
{
BaseUIForm wannaShowForm = null;
BaseUIForm wannaShowFormInAllFormsDic = null;
//事先检查该窗体是否已经显示过了,已显示就不再往当前显示集合_DicCurrentShowUIForm里放了(1)
_DicCurrentShowUIForms.TryGetValue(uiFormName,out wannaShowForm);
if(wannaShowForm)
{
Debug.Log("已经显示过了");
return;
}
//把普通窗体_DicCurrentShowUIForm集合、反向切换窗体_StaCurrentShowUIForm,这两个集合中的窗体统统关闭——然后,把要显示的窗体放到_DicCurrentShowUIForm集合中+显示(2)
foreach (BaseUIForm baseUIForm in _DicCurrentShowUIForms.Values)
{
baseUIForm.Hide();
}
foreach(BaseUIForm baseUIForm in _StaCurrentShowUIForms)
{
baseUIForm.Hide();
}
_DicAllUIForms.TryGetValue(uiFormName,out wannaShowFormInAllFormsDic);
_DicCurrentShowUIForms.Add(uiFormName,wannaShowFormInAllFormsDic);
wannaShowFormInAllFormsDic.Display();
}
private bool ClearStackArray()//不同窗体切换引发混乱?
{
if(_StaCurrentShowUIForms!=null&&_StaCurrentShowUIForms.Count>1)
{
_StaCurrentShowUIForms.Clear();
return true;
}
return false;
}
#endregion
#region 关闭窗体 系列方法
/// <summary>
/// 关闭窗体:
/// 根据窗体的不同显示类型,进项操作(2)
/// 事先进行参数检查:字符换是否为空+是否加入所有窗体缓存(1)
/// </summary>
/// <param name="uiFormName"></param>
public void CloseUIForm(string uiFormName)
{
BaseUIForm wannaCloseForm=null;
if (string.IsNullOrEmpty(uiFormName))
{
Debug.Log("名字为空");
return;
}
if (!_DicAllUIForms.TryGetValue(uiFormName, out wannaCloseForm))
{
Debug.Log("想要关闭的窗体在_DicAllUIForms中不存在,请检查名字,如果名字正确请检查Json中元素" + uiFormName);
return;
}
else
{
switch(wannaCloseForm.CurrentUIType.UIForm_ShowMode)
{
case UIFormShowMode.Normal:
CloseUIForm_Normal(uiFormName);
break;
case UIFormShowMode.ReverseChange:
CloseUIForm_ReverseChange();
break;
case UIFormShowMode.HideOther:
CloseUIForm_HideOther(uiFormName);
break;
}
}
}//Method_end
/// <summary>
/// 普通窗体的关闭:
///
/// </summary>
/// <param name="uiFormName"></param>
public void CloseUIForm_Normal(string uiFormName)
{
BaseUIForm wannaCloseForm = null;
if(!_DicCurrentShowUIForms.TryGetValue(uiFormName, out wannaCloseForm))
{
Debug.Log("想要关闭的窗体在_DicCurrentShowUIForm中不存在,请检查Json中元素" + uiFormName);
}
else
{
_DicCurrentShowUIForms.Remove(uiFormName);
wannaCloseForm.Hide();
}
}
/// <summary>
/// 反向切换窗体的关闭:
/// 如果栈中只有1个,直接出栈,并隐藏;
/// 如果栈中有2个以上,出栈+并隐藏后,取得栈顶元素,显示
///
/// </summary>
/// <param name="uiFormName"></param>
public void CloseUIForm_ReverseChange()//没有参数吗?
{
if(_StaCurrentShowUIForms.Count>=2)
{
BaseUIForm wannaCloseForm = _StaCurrentShowUIForms.Pop();
wannaCloseForm.Hide();
BaseUIForm topFormInStack= _StaCurrentShowUIForms.Peek();
topFormInStack.Replay();
}
else if(_StaCurrentShowUIForms.Count == 1)
{
BaseUIForm wannaCloseForm=_StaCurrentShowUIForms.Pop();
wannaCloseForm.Hide();
}
}//Method_end
/// <summary>
/// 隐藏其它窗体的关闭:把它从当前显示窗体集合中找出来,隐藏并移出集合+先前Show的时候关掉的两个集合重新显示
/// </summary>
public void CloseUIForm_HideOther(string uiFormName)
{
//把窗体类从当前显示UI集合中移除,让该集合中元素都显示;
BaseUIForm wannaCloseForm = null;
_DicCurrentShowUIForms.TryGetValue(uiFormName,out wannaCloseForm);
if (!wannaCloseForm)
{
Debug.Log("当前显示窗体集合中,没有此窗体" + uiFormName);
return;
}
wannaCloseForm.Hide();
_DicCurrentShowUIForms.Remove(uiFormName);
foreach(BaseUIForm baseUIForm in _DicCurrentShowUIForms.Values)
{
baseUIForm.Replay();
}
foreach(BaseUIForm baseUIForm in _StaCurrentShowUIForms)
{
baseUIForm.Replay();
}
//此时不一定有 反向切换窗体在显示啊
}
#endregion
#region 显示“UIManager”核心数据,供测试使用
//显示所有窗体的数量
public int ShowAllUIFormsCount()
{
if(_DicAllUIForms!=null)
{
return _DicAllUIForms.Count;
}
else
{
return 0;
}
}
//显示“当前显示窗体”的数量
public int Show_DicCurrentShowUIFormsCount()
{
if (_DicCurrentShowUIForms != null)
{
return _DicCurrentShowUIForms.Count;
}
else
{
return 0;
}
}
//显示栈里窗体的数量
public int Show_StackCurrentShowUIFormsCount()
{
if (_StaCurrentShowUIForms != null)
{
return _StaCurrentShowUIForms.Count;
}
else
{
return 0;
}
}
#endregion
//路径字典集合,Json数据载入
private void Init_DicUIFormPaths_Data()
{
ConfigManagerByJson configManagerByJson = new ConfigManagerByJson(SystemDefine.SYS_JsonName_path);
if(configManagerByJson!=null)
{
_DicUIFormPaths=configManagerByJson.AppSetting;
}
}
}//Class_end
}
UI框架——核心类 UIManager.cs
最新推荐文章于 2024-05-20 09:49:56 发布