ngui 渲染顺序
1通过UIWidget的depth 来排序UIWWidget
2UIPanel在FillAllDrawCalls 里根据排序后的UIWidget 生成UIDrawcall
3然后在UpdateDrawCalls 里根据drawCalls 的顺序 和panel的 renderq 来生成 每个 UIDrawcall的randerqueue
所以实现插入粒子系统进去需要
1设置粒子系统在UIPanel的depth 来插入到两个UIWidget中间。
2 然后ngui根据UIPanel的全部Widget分拆合并UIDrawCall 这时候记录下根据depth插入到第几个UIDrawCall
3在UIDrawCall 生成的时候 如果是要插入的UIDrawCall 就把renderqueue给了例子系统 然后UIDrawCall的 renderqueue 加1
记录插入几个粒子系统
public class UIRenderSort : MonoBehaviour {
public UIPanel panel;
public int depth;
public int renderQuene;
[HideInInspector]
public int drawCallID;
[HideInInspector]
public bool isDrity;
void Awake()
{
panel.AddSortUI(this);
}
void Destory()
{
panel.RemoveSortUI(this);
}
public virtual void FillDrawCall()
{
}
}
在UIPanel 增加
public List<UIRenderSort> sortUIs= new List<UIRenderSort>();
public void AddSortUI(UIRenderSort ui)
{
if (!sortUIs.Contains(ui))
sortUIs.Add(ui);
}
public void RemoveSortUI(UIRenderSort ui)
{
sortUIs.Remove(ui);
}
在LateUpdate插入
void LateUpdate ()
{
#if UNITY_EDITOR
if (mUpdateFrame != Time.frameCount || !Application.isPlaying)
#else
if (mUpdateFrame != Time.frameCount)
#endif
{
mUpdateFrame = Time.frameCount;
// Update each panel in order
for (int i = 0, imax = list.Count; i < imax; ++i)
list[i].UpdateSelf();
int rq = 3000;
// Update all draw calls, making them draw in the right order
for (int i = 0, imax = list.Count; i < imax; ++i)
{
UIPanel p = list[i];
//slc begin
if (p.renderQueue == RenderQueue.Automatic)
{
p.startingRenderQueue = rq;
p.UpdateDrawCalls();
rq += p.drawCalls.Count + sortUIs.Count;
}
else if (p.renderQueue == RenderQueue.StartAt)
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count + sortUIs.Count);
}
//slc end
else // Explicit
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startingRenderQueue + 1);
}
}
}
}
在FillAllDrawCalls 插入 实现在ngui重新生成UIDrawCall 的时候 记录下插入第几个drawcall
void FillAllDrawCalls ()
{
for (int i = 0; i < drawCalls.Count; ++i)
UIDrawCall.Destroy(drawCalls[i]);
drawCalls.Clear();
Material mat = null;
Texture tex = null;
Shader sdr = null;
UIDrawCall dc = null;
int count = 0;
if (mSortWidgets) SortWidgets();
//slc begin
List<UIRenderSort> list = new List<UIRenderSort>();
list.AddRange(sortUIs);
for (int i = 0; i < widgets.Count; ++i)
{
UIWidget w = widgets[i];
if (w.isVisible && w.hasVertices)
{
Material mt = w.material;
Texture tx = w.mainTexture;
Shader sd = w.shader;
bool isAddSortUI = false;
if (list.Count > 0)
{
for (int u = 0; u < list.Count; u++)
{
if (list[i].depth < w.depth)
{
isAddSortUI = true;
list[i].drawCallID = i;
list.Remove(list[i]);
}
}
}
if (mat != mt || tex != tx || sdr != sd || isAddSortUI==true)
{
//slc end
在 UpdateDrawCalls插入 实现更新renderqueue
void UpdateDrawCalls ()
{
Transform trans = cachedTransform;
bool isUI = usedForUI;
if (clipping != UIDrawCall.Clipping.None)
{
drawCallClipRange = finalClipRegion;
drawCallClipRange.z *= 0.5f;
drawCallClipRange.w *= 0.5f;
}
else drawCallClipRange = Vector4.zero;
// Legacy functionality
if (drawCallClipRange.z == 0f) drawCallClipRange.z = Screen.width * 0.5f;
if (drawCallClipRange.w == 0f) drawCallClipRange.w = Screen.height * 0.5f;
// DirectX 9 half-pixel offset
if (halfPixelOffset)
{
drawCallClipRange.x -= 0.5f;
drawCallClipRange.y += 0.5f;
}
Vector3 pos;
if (isUI)
{
Transform parent = cachedTransform.parent;
pos = cachedTransform.localPosition;
if (clipping != UIDrawCall.Clipping.None)
{
pos.x = Mathf.RoundToInt(pos.x);
pos.y = Mathf.RoundToInt(pos.y);
}
if (parent != null) pos = parent.TransformPoint(pos);
pos += drawCallOffset;
}
else pos = trans.position;
Quaternion rot = trans.rotation;
Vector3 scale = trans.lossyScale;
//slc begin
int offset = 0;
for (int i = 0; i < drawCalls.Count; ++i)
{
UIDrawCall dc = drawCalls[i];
Transform t = dc.cachedTransform;
t.position = pos;
t.rotation = rot;
t.localScale = scale;
if (sortUIs.Count > 0)
{
for (int u = 0; u < sortUIs.Count; u++)
{
if (sortUIs[u].drawCallID == i)
{
sortUIs[u].renderQuene = startingRenderQueue + i + offset;
sortUIs[u].FillDrawCall();
offset += 1;
}
}
}
dc.renderQueue = (renderQueue == RenderQueue.Explicit) ? startingRenderQueue : startingRenderQueue + i + offset;
//slc end
dc.alwaysOnScreen = alwaysOnScreen &&
(mClipping == UIDrawCall.Clipping.None || mClipping == UIDrawCall.Clipping.ConstrainButDontClip);
dc.sortingOrder = mSortingOrder;
dc.clipTexture = mClipTexture;
}
}