作为一个做项目时经常碰到的问题,我想还是好好总结一下,所谓的”三明治“问题,就是在两个NGUI的控件(widgetFront和widgetAfter)中间插入3D模型(model)。
目前我觉得比较靠谱的方法有两个:
1.把三层剥离出来,分别用一个单独的摄像机去渲染,然后调整摄像机的depth,这个方法就不详细说明了;
2.对于摄像机中物件渲染的前后关系,是由render queue的大小决定的,大者在前,明白这个原理,那我们就需要调整三层的render queue,widgetFront > model > widgetAfter,实施细则如下,NGUI版本是3.7.0
编写脚本,这个脚本是要附在model上的,
public class ChangeRQ : MonoBehaviour
{
// widgetFront和widgetAfter用UIPanel隔离开,此panel为widgetAfter所在UIPanel
public UIPanel panel;
public UIWidget widgetAfter;
void Awake()
{
panel.AddOther(this);
}
void OnDestroy()
{
if (panel != null) panel.RemoveOther(this);
}
// 更新model的render queue,保持它的值大于widgetAfter
public void UpdateRQ()
{
if (widgetAfter != null && widgetAfter.drawCall != null)
{
int rq = widgetAfter.drawCall.renderQueue + 1;
foreach (Material ma in renderer.materials)
{
if (ma.renderQueue != rq)
{
ma.renderQueue = rq;
}
}
}
}
}
找到UIPanel的LateUpdate函数,查看一下渲染前后关系的具体实现,大概是根据三种不同类型的UIPanel分别设置起始值,整个NGUI的起始值是3000,进而实现每一层UIPanel的前后绘制关系,那么我们就要做对应的修改,把每一层UIPanel之间的间隔全部double,留出层级位置给model绘制,具体修改如下
void LateUpdate()
{
// ...
if (p.renderQueue == RenderQueue.Automatic)
{
p.startingRenderQueue == rq;
p.UpdateDrawCalls();
rq += p.drawCalls.Count;
}
else if (p.rendrerQueue == RenderQueue.StartAt)
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startintRenderQueue + p.drawCalls.Count);
}
else
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startintRenderQueue + 1);
}
// ...
}
改为
void LateUpdate()
{
// ...
if (p.renderQueue == RenderQueue.Automatic)
{
p.startingRenderQueue == rq;
p.UpdateDrawCalls();
rq += p.drawCalls.Count * 2;
}
else if (p.rendrerQueue == RenderQueue.StartAt)
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startintRenderQueue + p.drawCalls.Count * 2);
}
else
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
rq = Mathf.Max(rq, p.startintRenderQueue + 1 * 2);
}
UpdateModelRQ();
// ...
}
List<ChangeRQ> list = new List<ChangeRQ>();
public void AddOther(ChangeRQ changeRQ)
{
if (!list.Contains(changeRQ)) list.Add(changeRQ);
}
public void RemoveOther(ChangeRQ changeRQ)
{
list.Remove(changeRQ);
}
public void UpdateModelRQ()
{
for (int i = 0; i < list.Count; i++)
{
list[i].UpdateRQ();
}
}
Tips : 代码纯手打,如有错误多多指正哦,另外,这只是一个sample,具体问题要具体对待哦!
版权所有jklrty,如需转载请注明出处;-)