找到一个不用添加多个Camera在两个UI中叠加UI特效的方法。如下图所示,两个Image之间放了个UI特效。
上代码:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class UIDepth : MonoBehaviour {
public int order;
public bool isUI = true;
void Start ()
{
if(isUI){
Canvas canvas = GetComponent<Canvas>();
if( canvas == null){
canvas = gameObject.AddComponent<Canvas>();
}
canvas.overrideSorting = true;
canvas.sortingOrder = order;
}
else
{
Renderer []renders = GetComponentsInChildren<Renderer>();
foreach(Renderer render in renders){
render.sortingOrder = order;
}
}
}
}
原理就是设置 sortingOrder ,给需要修改order的UI元素挂上UIDepth脚本 。如下图所示,在UI容器中设置order。
注意: UI0 我设置了order =0 (可以不设置,因为默认所有UI的Order都是0)
ParticleSystem 我设置了order =1
UI2 我设置了order =2
所以效果是,UI2 挡住 ParticleSystem 挡住 UI0
这段代码必须运行了才能看到效果。
补充一下 Unity5.3的粒子特效里已经有sortingOrder属性了,也就是说以后就不需要加Canvas组件了。如下图所示
- 本文固定链接: https://www.xuanyusong.com/archives/3435
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!




老师,我用了这个方法结果按钮不能点击了是什么情况那?
雨松老师你好,在这方面我有个疑问,上文所述方法,针对的是粒子特效,但是UI特效的制作时,并不是所有部分都是粒子,这个时候通过这个方法实现,就会出现一个特效中,其粒子部分正常,非粒子部分还是会被UI挡住,这种情况有什么好的解决方法吗?
分两部分就行, 特效只做特效。 然后设置不同的深度 拼起来
雨松老师你好,根据上文所述方案,我得到启示,canvas下分三个tag层(buttomLayer、NormalLayer和topLayer)来管理UI叠层,分别挂上canvas组件,sortingOrder分别为0,10,20,每个要挂在UI上的特效,其粒子的render对应的sortingOrder分别设置为UI所在tag层对应sortingOrder,这样就能很好的解决了特效与UI叠层冲突的问题,但是同时我发现一些bug,就是有些buttom层和normal层的UI,偶尔有时候渲染不出来!但不是必现的!雨松老师能不能指点一二
http://blog.csdn.net/akailee/article/details/51798288 你们两个哪个是正版。我糊涂了
用的都是雨松的图片,你说呢?
你好,我想请问一下,sorting order和sorting layer本身是给unity 2D提供的,网上很多博客说它们的控制渲染顺序优先级比renderQueue还高,NGUI的panel的order和depth就证明了,但是我想不通为什么,sorting order和sorting layer到底控制了渲染中哪个属性了,请雨松大神解答一下?
MeshRenderer m = GetComponent();m.sortingOrder = 10我使用这段代码修改了3d物体的MeshRenderer,为什么还是会被UI挡到
因为3D物体的Z的渲染区域 和UI的区域不一样。 必须同样都是一个片才行。。。
这样就是说3D物体和UI是没办法用sortingOrder 这个属性修改咯,本来以为可以用这个属性简单解决,结果还是要用多个深度摄像机的方式
可以renderTexture
HI,雨松,有什么方法可以让UGUI始终渲染在3D模型前面呢?除了添加多个摄像头。
hi雨松问下如果有粒子特效常驻场景中,如游戏中的一些充值活动按钮的闪光效果,那后续打开的功能类面板都要显示在这些闪光效果上面,是不是后续打开的面板都要加类似uidepth脚本处理叠层的关系呢,如果是的话,那就是场景中有粒子特效常驻显示的话,在打开显示的面板都要加canvas组件来处理夹层,累觉不爱啊
我是这样做的, 因为不是所有界面都要有特效、大部分界面是没有特效的。 我做了一个脚本 给需要修改层级的加上这个脚本。 每个界面我会加100 .也就是这个界面下面的深度是 (N*100 ) + Order 自动把canvas 的order设置正确。 如果都没有的话 就不需要加这个canvas 一切都是自动的。。 所以 这样做界面的人不需要考虑多个界面夹层的问题。。
hi 你的方案是不是要维护一个全局的order,新打开的UI都以全局order计算各自的order值,同时刷新全局order,这样拼UI的同学就不用关心界面与界面之间的穿插关系,只要注意本UI不会有穿插问题就可以了。但是这样有一个问题,每次打开一个有特效的新的UI都会引起全局order自增,但却没办法让它减下来,会不会出现什么问题?我们现在项目无法保证关闭的一定是最近打开的UI,所以关闭UI的时候让全局order自减没法实现,请问下你是怎么解决这个问题的,或者有什么好的建议,谢谢了
我是这样做的, 因为不是所有界面都要有特效、大部分界面是没有特效的。 我做了一个脚本 给需要修改层级的加上这个脚本。 每个界面我会加100 .也就是这个界面下面的深度是 (N*100 ) Order 自动把canvas 的order设置正确。 如果都没有的话 就不需要加这个canvas 一切都是自动的。。 所以 这样做界面的人不需要考虑多个界面夹层的问题。。
是不是可以这么理解:如果想在UGUI中显示特效就必须对所有UI的sortingOder进行管理?我之前的UI都是使用的默认sortingOrder,也就是都是0,现在用到特效了,是不是要对之前的UI的sortingOrder进行管理?我之前用的z值来控制的,本来想用z值就都用z值,用sortingOrder就都用sortingOrder这样逻辑清晰,如果答案是肯定的可能还需要改之前的逻辑。
Z值是有效的。 sortingorder主要是解决 UI 与 特效叠层的情况。
但是我的UI都是使用的默认sortingOrder都是0。粒子只能在所有UI最前面或者所有UI最后面显示,不能插入到中间某一层显示。我查了下资料,好像Canvas下的所有东西都在一个渲染层级中。所以会出现只能在UI最前或者最后显示粒子的问题。上面的方法确实能解决问题,但是,这个方法需要从项目初期就对sortingOrder有一个统一的管理才行,需要提前预留出哪些层是专门显示特效的。我现在的方法是我是用几个RectTransform作为container通过z值来进行的分层管理,但是粒子不认z值,只认renderqueue或者你上面方法中的sortingOrder。我理解的没问题吧?松神?我现在的问题是想根你确定一下,是不是如果我UI中想用粒子特效一定要对sortingOrder进行统一管理,并且提前预留出相应的order值区间?
嗯 ,如果UI中需要叠层粒子, 就留几个order的区间给它就行了
挂载之后就不响应button事件..这样就好了:gameObject.AddComponent()
要响应事件的话 要加Graphic Raycaster
如果特效可以做成一个组件就好了,类似CavansRenderer,管好界面和界面之间,界面和特效之间层级关系就方便了,但是貌似做不了[可怜]
是的, 我以前给UGUI的作者提过建议, 他说后面会支持。。。 所以我们就等待吧。。
scrollview 在camera模式下不能使用 只能在overlay 或者 world 模式下才能用 ,如果在overlay模式下,少量特效可以rendertotexture去处理 但是如果多的话 那效率上就差太多了 world 模式下所有的UI布局缩放都被强制的改变了。。我想用到scrollview的同时用particul,momo大神有什么好办法么?
我现在的项目中,添加了多个层:ViewLayer/TipLayer/DialogLayer,每个层上挂一个UIDepth,在修改这些Layer下的Panel的SetActive属性时,内存会不断增加,请问momo有没有遇到这样的情况?这是unity3d的BUG吗?
layer 只是会增加drawcall
我觉得2D的渲染顺序真是unity的一个硬伤,官方的说法是:渲染时会按SortingLayer再按SortingOrder,如果这些都一样,就优先渲染离摄像机近的(Depth),但是这个Depth怎么修改,我还没学会。如果Depth也没区别才按Z轴顺序。其实我觉得2D游戏的话直接用Z轴,不管是设计还是运行时层级都很清晰
多谢贡献, 在没有子目录的UI中可以正常,但是在一个UI控件包含有子UI控件时候,特效却和UI遮挡出现了混乱,怎么调都不对,请问大拿这个怎么处理呢?
你忘记写一个重要的前提 canvs的Render Mode必须为 screenspace-camera
请问NGUI有没有办法实现
用了这个方法后,input,button之类的都坏掉不能用了,有什么解决办法么
用 @老蛙 的办法解决了
这种方法中粒子效果与UI是用同一个相机渲染,那么美术就必须在UI相机下设计粒子效果?
恩,是的。
还有一种办法,就是把Canvas的plancedistance设置成跟主视角相同的距离就好了,这样基本能够1:1
而且能够通用
momo老师,这个脚本不能挂载在Button上吗?为什么挂载之后就不响应button事件了。我想用这个方法实现两个层级的按钮切换效果
UI组件的order默认是0,别挂UIDepth组件,比如你要在全屏UI背景上加个全屏UI特效,只需要在特效上加个UIDepth,order为-1,然后在背景图上加个为-2的。就不会遮挡界面的任何事件了
我用这个方法设置以后,之前可以相应的button点击,现在点击都没有任何反应了,这个是什么原因呢?
我也遇到这个问题了
额~~~~,求解决方案
我用2个SpriteRender 加z轴控制做叠加了。没用他这个方法
还要加个Raycast 那个组件,不然接收不到射线
是Graphic Raycaster
其实 只需要给ParticleSystem加上这个就好了,UI的话直接改Canvas的OrderInLayer
这是一个道理, 只是有些是运行时动态算的, 我觉得尽量把脚本封装的简单易用即可。。