實作的功能是可以讓特效顯示在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
{
}
}
}