实现的功能是可以让特效显示在UI层级之间或者一直保持在UI最前面。
不管是NGUI还是特效最终都是通过RenderQueue控制的。
问题是我们怎么获取一个特效RenderQueue让他刚好在UI元素之间?
通过NGUI Texture2D(单独的drawcall)的显示规则来获取RenderQueue然后赋值给特效,相当于特效的显示规则和Texture2D一样了。
这里需要注意特效的sortingOrder必须和UI一样。
代码如下
using UnityEngine;
[RequireComponent(typeof(UIInvisibleWidget))]
public class UIInVisibleSort : MonoBehaviour
{
// 是否显示在UI的最上层
public bool isTop = true;
// 用来调试显示
public int renderQueue_ReadOnly;
// 特效的渲染
private Renderer[] _renderers;
// 通过NGUI分配的UIWidget
private UIInvisibleWidget _widget;
// 是否已经排序了
private bool _isSort = false;
// 是否晚一帧调整特效层级
private bool _IsFrameDelay = false;
public void SortTop()
{
int maxDepth = _widget.depth;
if (isTop)
{
UIPanel parentPanel = transform.GetComponentInParent<UIPanel>();
if (parentPanel)
maxDepth = parentPanel.GetMaxUIWightDepth() + 1;
}
Sort(maxDepth);
}
public void Sort(int depth)
{
_widget.depth = depth;
_isSort = true;
}
void Awake()
{
_widget = gameObject.GetComponent<UIInvisibleWidget>();
_renderers = gameObject.GetComponentsInChildren<Renderer>();
}
void Start()
{
_IsFrameDelay = true;
SortTop();
}
void Update()
{
if (_IsFrameDelay)
{
_IsFrameDelay = false;
return;
}
if (!_isSort)
return;
if (_widget == null || _widget.drawCall == null || _renderers == null)
{
return;
}
_isSort = false;
renderQueue_ReadOnly = _widget.drawCall.renderQueue;
foreach(Renderer render in _renderers)
{
//render.sortingOrder = 0;
render.material.renderQueue = renderQueue_ReadOnly;
}
}
[ContextMenu("ReExcute")]
void ReExcute()
{
_isSort = true;
}
#if UNITY_EDITOR
void OnValidate()
{
_isSort = true;
if (_widget)
{
_widget.drawCall.renderQueue = renderQueue_ReadOnly;
}
}
#endif
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class UIInvisibleWidget : UIWidget
{
private Texture2D mTex;
private Material mMat;
protected override void Awake()
{
base.Awake();
height = 0;
width = 0;
mTex = new Texture2D(0, 0);
mChanged = false;
fillGeometry = false;
geometry.verts.Add(new Vector3(1f, 0, 0));
geometry.verts.Add(new Vector3(2f, 0, 0));
geometry.verts.Add(new Vector3(3f, 0, 0));
geometry.verts.Add(new Vector3(4f, 0, 0));
geometry.ApplyTransform(Matrix4x4.identity);
geometry.uvs.Add(Vector2.zero);
geometry.uvs.Add(Vector2.up);
geometry.uvs.Add(Vector2.one);
geometry.uvs.Add(Vector2.right);
geometry.cols.Add(Color.white);
geometry.cols.Add(Color.white);
geometry.cols.Add(Color.white);
geometry.cols.Add(Color.white);
}
public override Texture mainTexture
{
get
{
return mTex;
}
set
{
}
}
public override Material material
{
get
{
return mMat;
}
set
{
}
}
}