您的位置:首页 > 产品设计 > UI/UE

NGUI与3d模型的<三明治>问题

2015-09-06 16:04 375 查看
作为一个做项目时经常碰到的问题,我想还是好好总结一下,所谓的”三明治“问题,就是在两个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,如需转载请注明出处;-)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: