使用UGUI时,经常需要设置UI上的层级。
1.先来说说我们的问题:由于unity渲染物体时是从上到下直接渲染的,这就导致了渲染出来的效果和我们预期的不一致,因此必须设置层级,指定渲染的先后顺序(层级低的先渲染)才行。
那么问题来了,UGUII并没有NGUI这么方便的提供设置层级的入口。
2.我们必须给UI添加一个组件(Canvas)来设置UI层级
但是坑爹的是:设置完后,层级的问题解决了,但是UI的所有事件被拦截(包括按钮的点击、UI拖拽等等)
3.终极解决方案:给UI再设置一个组件Graphic Raycster,完美解决,既可以显示特效,还不会遮挡UI。
至此有个问题,如果界面很多都需要设置上述的canvas,那就需要自己实现一个管理类,给每个ui设置它的order,不过canvas会影响合并批次,所以不能有太多,自己权衡。
public class UIManager : MonoBehaviour
{
/// 窗口的排序层集合
public static Dictionary<string, int> _DicUIFormSortLayerCount;
//初始化核心数据,加载"UI窗体路径"到集合中
private void Awake()
{
//字段初始化
_DicUIFormSortLayerCount = new Dictionary<string, int>
{
{ "SelectTipsUI",40 },
{"DiceUI",20 },
{ "GetItemBoxUI",20},
{ "MissionTipsUI",20},
{ "RandomEventUI",20},
{ "RandomShopUI",20},
{ "ShopGoodsInfoUI",25}
};
_DicAllUIForms = new Dictionary<string, BaseUIForm>();
_DicCurrentShowUIForms = new Dictionary<string, BaseUIForm>();
_DicFormsPaths = new Dictionary<string, string>();
_StaCurrentUIForms = new Stack<BaseUIForm>();
_StaChildUIForm = new Stack<BaseUIForm>();
//初始化加载Canvas根预设
InitRootCanvasLoading();
//得到UI根节点、全屏节点、固定节点、弹出节点
_TraCanvasTransform = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS).transform;
_TraNormal = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_NORMAL_NODE);
_TraFixed = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_FIXED_NODE);
_TraPopUp = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_POPUP_NODE);
_TraGuide = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_GUIDE_NODE);
_TraUIScripts = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject, SysDefine.SYS_SCRIPTMANAGER_NODE);
_TraSavePrefab = UnityHelper.FindTheChildNode(_TraCanvasTransform.gameObject,SysDefine.SYS_SAVEPREFAB_NODE);
}
=========================================================================
/// 基础UI窗体
public class BaseUIForm : MonoBehaviour
{
/// 重置层序
public void ResetCanvasSortLayer()
{
if (UIManager._DicUIFormSortLayerCount.ContainsKey(name))
{
this.GetComponent<Canvas>().sortingOrder = UIManager._DicUIFormSortLayerCount[name];
}
}
==========================================================================
public class UIMaskManager : MonoBehaviour
{
/// 设置遮罩状态
/// </summary>
/// <param name="objDisplay">需要显示的UI窗体</param>
/// <param name="LucenyType"></param>
public void SetMaskWindow(GameObject objDisplay,UIFormLucenyType LucenyType = UIFormLucenyType.Lucency)
{
if (LucenyType == UIFormLucenyType.DnotMask)
{
//显示窗体下移
objDisplay.transform.SetAsLastSibling();
//增加当前UI摄像机的层深(保证当前相机为最前显示)
if (_UICamera != null)
{
_UICamera.depth = _UICamera.depth + 100;
}
return;
}
Canvas _MaskCanvas = _objMaskPanel.GetOrAddComponent<Canvas>();
_objMaskPanel.GetOrAddComponent<GraphicRaycaster>();
//顶层窗体下移
_objTopPanel.transform.SetAsLastSibling();
if (UIManager._DicUIFormSortLayerCount.ContainsKey(objDisplay.name))
{
objDisplay.GetComponent<Canvas>().sortingOrder = UIManager._DicUIFormSortLayerCount[objDisplay.name]+2;
_MaskCanvas = _objMaskPanel.GetComponent<Canvas>();
_MaskCanvas.overrideSorting = true;
_MaskCanvas.enabled = true;
_MaskCanvas.sortingOrder = objDisplay.GetComponent<Canvas>().sortingOrder - 1;
}
else
{
if (_MaskCanvas != null)
{
Destroy(_objMaskPanel.GetComponent<GraphicRaycaster>());
Destroy(_MaskCanvas);
}
}
}
引用:https://blog.csdn.net/qq_34937637/article/details/81066890