NGUI与Unity3D物体渲染顺序问题,做UI的同学应该都遇到过。主要指的是UI与Unity制作的特效、3D人物等一同显示时的层次问题。

之前邓老师就这一问题,专门做了一次分享。邓老师在分享时也指出了这类问题的根源:由于UI与特效等都是以transparent方式渲染,而Unity与NGUI在管理同是透明物体的render queue时实际上互相没有感知,于是引出排序问题。邓老师介绍了以Render To Texture方式解决这一问题的一种方法,文档见svn: /wlgame_proj/trunk/Client/Doc/规范文档/UI上的特效显示.docx

然而使用rtt解决这类问题总感觉过重,且不够灵活;而且rtt为了兼顾效率,纹理不可能设置太大,所以也导致了渲染精度降低、细节丢失的问题。

今天尝试了另一种思路来解决这一问题:直接控制Unity中特效的render queue值,来达到使得UI、特效按照我们希望的顺序进行渲染的目的。

先上效果图,数字标注了不同的层次,按照0-7的顺序叠加:

测试的工程地址:

\\......\......\03.客户端\frank\UISandwichWithParticle.zip

测试场景为Assets\TestScene.unity。

另外这一工程中也包含了一个以邓老师的方式解决这一问题的示例,场景为Assets\TestScene_orig.unity。

首先参考一下邓老师方法中实现这类叠加后的Draw Call细节:

可以看到,因为所有元素最终都是以NGUI的元素进行管理的,draw call非常清晰,一层UI夹一层rtt纹理,render queue从3000开始依次排序下来,标准的多层三明治结构。

再来看另一种方式下UI的draw call细节:

这种方式下,UI和特效还是分开渲染的,所以NGUI的Draw Call统计里只能看到UI的4个dc。注意,这里手动设置了每个UI的render queue的值,分别是3000、3002、3004、3006,和上面的dc顺序参照相对应的关系,可以发现是把用于特效渲染的render queue值(3001、3003、3005)给预留了出来。

http://zzido.cn/home/article/view/id/65272.html

这里先插播一下关于设置UI的draw call的细节,也是这一方法中繁琐的部分。我们知道NGUI会将采用同样材质的widget合并到同一个draw call中进行渲染。然而在我们这个需求中,这一功能导致了无法在widget之间插入其它渲染队列的问题,也就是原始的三明治问题。如果只是涉及到UI控件之间的穿插,NGUI可以通过depth设置来解决:

如果是使用同一材质的多个控件设置了不同的depth值,则NGUI还是将这些控件合并为同一个draw call,而在内部进行了排序; http://m.zzido.cn/home/article/view/id/65273.html
如果设置了不同depth的多个控件,穿插使用了不同的材质,则NGUI会将其打散为不同的draw call,顺序即按照depth指定。邓老师的方式就用到的这一特性,其一共使用了2种材质而设置不同depth形成穿插关系,于是被打散成了7个dc。

http://www.zzido.cn/home/article/view/id/65272.html
我采用的方式,属于上述第一种情况,无法简单用depth设置来解决。为了将一个NGUI自动合并的dc打散,有多种hack的方式,这里选择的是手动给每个我们希望打散到不同dc的widget再添加一个panel的方式。增加panel原则上并不推荐,然而针对这一需求,实际上增加的空panel并不影响性能。其结果就是上图中所示。

http://m.zzido.cn/home/article/view/id/65272.html

在为每个归属于不同层次的widget指定了所属的render queue顺序之后,剩下的就是为每个unity的特效指定应归属的render queue。

这里引入了一个脚本:RenderQueueModifier.cs( https://www.zzido.cn/home/article/view/id/65272.html )。使用时,需要将这一脚本拖到对应的Unity的3D物体上

指定一个作为target的widget,以及排序方式即可。上图的例子中,指定的target为card1,type为FRONT,含义是将这一特效指定为在Card1控件的前面。

其原理也较为简单,直接贴源码: http://zzido.cn/home/article/view/id/65273.html

using UnityEngine;

using System.Collections;

public class RenderQueueModifier : MonoBehaviour

{

public enum RenderType

{

FRONT,

BACK

}

public UIWidget m_target = null;

public RenderType m_type = RenderType.FRONT;

柳断肠处长向尊前悲老大有人夫婿擅侯王当时只受声名累贵戚名豪竞延致照花前后镜花面交相  http://zzido.cn/home/article/view/id/65274.html

映新帖绣罗襦双双金鹧鸪折戟沈沙铁未销自将磨洗认前朝东风不与周郎便铜雀春深锁二乔阵阵轻寒细马骄竹林茅店小帘招东风已绿南溪水更染溪南万柳条峥嵘赤云西日脚下平地柴门鸟雀噪归客千里至之死矢靡它母也天只不谅人 http://www.zzido.cn/home/article/view/id/65274.html

只泛彼柏舟芷葺兮荷屋缭之兮杜衡合百草兮实庭建芳馨兮廡门中泠南畔石盘陀古来出没随涛波试登绝顶望乡国江南江北青山多中原干戈古亦闻岂有逆胡传子孙遗民忍死望恢复几处今宵垂泪痕中州盛日闺门多暇记得偏重三五铺翠冠儿捻金雪柳簇带争济楚如今憔悴风鬟霜鬓怕见夜间出去不如向帘 http://m.zzido.cn/home/article/view/id/65274.html 儿底下听

人笑语终愧巢与由未能易其节沈饮聊自适放歌破愁绝众芳摇落独暄妍占尽风情向小园疏影横斜水清浅暗香浮动月黄昏众鸟高飞尽孤云独去闲相看两不厌只有敬亭山重过阊门万事非同来何事不同归梧桐半 https://www.zzido.cn/home/article/view/id/65274.html  清霜后头白鸳鸯失伴飞重湖

叠巘清嘉有三秋桂子十里荷花羌管弄晴菱歌泛夜嬉嬉钓叟莲娃千骑拥高牙乘醉听箫鼓吟赏烟霞异日图将好景归去凤池夸重泉若有双鱼寄好知他年来苦乐与谁相倚我自中宵成转侧忍听湘弦重理待结个他生知已还怕两人俱薄命再缘悭剩月零风里清泪尽纸灰起昼出耘田夜绩麻村庄儿女各当家童孙未解供耕织也傍桑阴学种瓜朱门歌舞争新态绿绮尘埃试拂弦常恨闻名不相识相逢罇酒盍留连朱弦已为佳人绝青眼聊因美酒横万里归船弄长笛

Renderer[] _renderers;

int _lastQueue = 0;

void Start ()

{

_renderers = GetComponentsInChildren<Renderer>();

}

void FixedUpdate() {

if( m_target == null || m_target.drawCall == null )

return;

int queue = m_target.drawCall.renderQueue;

queue += m_type == RenderType.FRONT ? 1 : -1;

if( _lastQueue != queue )

{

_lastQueue = queue;

foreach( Renderer r in _renderers )

{

r.material.renderQueue = _lastQueue;

}

}

}

}

可以看到,原理上就是直接修改这一特效下所有renderer组建中的material的renderQueue值,来按照需要指定。

还是以上面截图的示例为例,Card1位于NGUI指定的render queue位置3000,则这个特效所在的render queue为3001,而在它之后render queue为3002的控件正好是控件Mask1。

所以和邓老师方案最终的render queue效果相比较,其实算是殊途同归,可以在不使用Render To Texture的情况下,达到更好的效果。

TODO:

偷懒所以手动添加的panel直接放在widget上,导致ngui会提示一条错误日志。这个按照规范,将panel与widget设为父子结构即可 http://www.zzido.cn/home/article/view/id/65273.html
RenderQueueModifier.cs脚本还有优化的余地,特别是可以增强编辑器支持,来达到不启动游戏即可实时查看叠加效果的功能。
这个方案测试是在老版本的NGUI3.0.6中进行的。3.6版的新NGUI中,引入了手动修改render queue的功能,会更加方便为每个ui指定所属的render queue。

转载于:https://www.cnblogs.com/dlqp9/p/10850540.html

unity实用技能,控制renderQueue解决NGUI与Unity3D物体渲染顺序问题相关推荐

  1. NGUI与Unity3d物体交叉显示的一种解决方案

    在项目的开发过程中,很多做过UI的同学估计都会遇到NGUI与unity3d物体的交叉显示问题,不知道如何处理,或者各种各样的界面穿插问题,界面层级混乱,对于界面来说,这些应该算是一个很严重的问题.在之 ...

  2. 【小松教你手游开发】【unity实用技能】u3d 层次问题总结

    首先的首先,NGUI区分前后层次关系是用Depth值.已经跟z轴值无关 首先因为我自己用的是NGUI,所以我的u3d层次问题也就是NGUI的层次问题 先确定UI渲染顺序,Camera>UIPan ...

  3. 【100个 Unity实用技能】| C# 中List 使用Exists方法判断是否存在符合条件的元素对象

    Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...

  4. Unity中的物体渲染顺序

    big seven 文章目录 前言 一.摄像机渲染 二.划分渲染队列 三.不透明物体的渲染 四.透明物体的渲染 五.UGUI元素的渲染 总结 前言 Unity中物体的渲染顺序 提示:以下是本篇文章正文 ...

  5. 【小松教你手游开发】【unity实用技能】unity游戏移植到WindowsPhone8平台上的一些...

    最近在移植u3d的游戏到WindowsPhone8上,WindowsPhone有多蛋疼就不说,移植的过程中还各种问题,稍稍总结一下 1.WindowsPhone账号在电脑上注册不要在手机上.手机上我就 ...

  6. 【小松教你手游开发】【unity实用技能】给每个GameObject的打开关闭加上一个渐变...

    在游戏开发中,经常会因为直接将GameObject,setActive的方式打开关闭,这种方式效果太过生硬而给它加上一个Tween 可能是AlphaTween或者ScaleTween. 再加上一个Pl ...

  7. 【小松教你手游开发】【unity实用技能】InvalidOperationException: ou

    InvalidOperationException: out of sync 在unity开发中出现这个bug. 在网上查了下是在迭代器中直接修改引起的.c#是不允许你在迭代器中直接修改. 改了一下确 ...

  8. 【小松教你手游开发】【unity实用技能】网游同步技术

    http://www.skywind.me/blog/archives/1343 转自http://www.skywind.me/blog/archives/1343 实时动作游戏在近年来得到迅猛的发 ...

  9. 【100个 Unity实用技能】| 游戏中使技能或装备跟随角色环绕,持续旋转

    Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...

  10. 【100个 Unity实用技能】 | Unity 在代码中 动态改变RectTransform位置及宽高 的方法整理

    Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 . 包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助 Unity 将创意 ...

最新文章

  1. 温故而知新:MySQL 四种隔离级别,你还对答如流吗?
  2. SQL提交数据三种类型
  3. hihocoder #1343 : Stable Members(支配树)
  4. 基于vue的颜色选择器vue-color-picker
  5. aes解压命令 linux,Linux使用tar和openssl加密和解密文件
  6. python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
  7. which与whereis区别
  8. 官网的python下载安装后无需配置即可使用_图文解说少儿编程软件python下载安装,没有经验的新手也可以做到...
  9. matlab低通滤波器库函数代码_Matlab中模拟低通滤波器的函数
  10. 牛客 2021年度训练联盟热身训练赛第二场 I题Pegasus Circle Shortcut
  11. 如何在Linux中使用sFTP上传或下载文件与文件夹
  12. 在 可编辑的 Div 的 光标位置 插入 文字 或 HTML
  13. 计算机丢失w95scm.dll,修复w95scm.dll
  14. fastadmin上传视频的操作
  15. VC2015 运行库安装错误 0x80240017 解决过程
  16. PMP-5.项目范围管理-需求跟踪矩阵
  17. Qt 设置弹出控制台终端
  18. HBase的java代码开发(完整源码)
  19. IDEA必备好用插件合集
  20. 【C++】vector添加元素

热门文章

  1. 3ds max基础知识
  2. 用XOM编写GraphML?
  3. 针对VC++ 上各种方法获取时间差,CSpanTime等
  4. 蓝桥杯2021年PYTHON 真题,跳房子
  5. java 笔画排序_Java汉字排序(3)按笔划排序
  6. 【信号处理】扩展卡尔曼滤波EKF(Matlab代码实现)
  7. Python3,一行代码实现文件夹共享,看到结果我酸了~
  8. [PhotoShop]用ps制作遮罩图层
  9. Windows 7 万能驱动下载 免费
  10. dnf第七章waiguaⅢ∨dnf第七章好感度【=dnf第七章免费外挂