NGUI用什么方式实现前后遮挡

2025-01-31 12:04:59
推荐回答(1个)
回答1:

解决方法是:
因为粒子系统的渲染顺序列默认为3000,而NGUI的渲染顺序默认也是从3000开始,当有嵌套的panel时或者Depth更高的panel时,GUI的渲染顺序会高于3000,

解决办法是,
1.修改Ngui中的UIPanel脚本中的默认的RenderQueue, 调整到3000以下,这样就不会遮挡住粒子特效了,当有的窗口需要显示在特效上面时,在检视面板中把该窗口的Renderer Q选项调整为Start At,值为3000以上,就可以解决,不过我的NGUI版本为3.1.6,所以可以直接调整。
2.使用另外一个摄像机,显示特效。但是在UI窗口相互切换时,不太好控制。
3.修改粒子特效的Shader中的RendererQueue值。

脚本 绑在特效上动态修改
Widget是遮挡者。。要在它之上播放,所以修改它的渲染队列 。Panel是要在哪个Panel之内播放。绑定就可以了..

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[AddComponentMenu("Custom/FixParticle")]
public class FixParticle : MonoBehaviour
{
public UIWidget widget;
public UIPanel panel;
public int renderQueue = 3000;
private bool mInitFlag = false;
void Start()
{
if (widget != null && widget.drawCall != null && mInitFlag == false)
{
mInitFlag = true;
FixRenderQueue(true);
}
}
void Update()
{
if (widget != null && widget.drawCall != null && mInitFlag == false)
{
mInitFlag = true;
FixRenderQueue(true);
}
}
private List mListParticleSystem = new List();
private List mListMeshRenderer = new List();
public void FixRenderQueue(bool reset)
{
Profiler.BeginSample("ParticleSystem:FixRenderQueue");
if (reset == true)
{
if (widget != null && widget.drawCall != null)
{
//widget.drawCall.AddFixParticle(this);
renderQueue = widget.drawCall.renderQueue;
}
else if (panel != null)
{
renderQueue = panel.startingRenderQueue;
}
mListParticleSystem.Clear();
mListMeshRenderer.Clear();
ParticleSystem[] pars = this.GetComponentsInChildren(true);
if (pars != null && pars.Length > 0)
{
for (int i = 0, max = pars.Length; i < max; i++)
{
ParticleSystem par = pars[i];
par.renderer.material.renderQueue = renderQueue;
mListParticleSystem.Add(par);
}
}
MeshRenderer[] meshs = this.GetComponentsInChildren(true);
if (meshs != null && meshs.Length > 0)
{
for (int i = 0, max = meshs.Length; i < max; i++)
{
MeshRenderer mesh = meshs[i];
mesh.material.renderQueue = renderQueue;
mListMeshRenderer.Add(mesh);
}
}
}
else
{
if (mListParticleSystem.Count < 1 || mListMeshRenderer.Count < 1)
{
FixRenderQueue(true);
}
else
{
bool needRefresh = false;
if (widget != null && widget.drawCall != null)
{
if (renderQueue != widget.drawCall.renderQueue)
{
renderQueue = widget.drawCall.renderQueue;
needRefresh = true;
}
}
else if (panel != null)
{
if (renderQueue != panel.startingRenderQueue)
{
renderQueue = panel.startingRenderQueue;
needRefresh = true;
}
}
if (needRefresh == true)
{
if (mListParticleSystem != null && mListParticleSystem.Count > 0)
{
for (int i = mListParticleSystem.Count - 1; i >= 0; i--)
{
ParticleSystem par = mListParticleSystem[i];
if (par != null)
{
par.renderer.material.renderQueue = renderQueue;
}
else
{
mListParticleSystem.RemoveAt(i);
}
}
}
if (mListMeshRenderer != null && mListMeshRenderer.Count > 0)
{
for (int i = mListMeshRenderer.Count - 1; i >= 0; i--)
{
MeshRenderer mesh = mListMeshRenderer[i];
if (mesh != null)
{
mesh.material.renderQueue = renderQueue;
}
else
{
mListMeshRenderer.RemoveAt(i);
}
}
}
}
}
}
Profiler.EndSample();
}
public void ResetRenderQueue()
{
FixRenderQueue(true);
}
}