找到一个不用添加多个Camera在两个UI中叠加UI特效的方法。如下图所示,两个Image之间放了个UI特效。
上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
大大,我测试时发现,三个物体我都添加脚本了,也设置好了,只是运行时,特效会渲染在最后面,等待两秒钟后,会自动跳到两个图片中间渲染,也就是运行时不能直接就得到想要的效果
高佳 ————-LJ?
雨松大大,请教一下,按照你的方法,我在Scene视图中能够实现效果,但是在Game视图却不能够显示出粒子,这是为什么?
老师,我用了这个方法结果按钮不能点击了是什么情况那?
雨松老师你好,在这方面我有个疑问,上文所述方法,针对的是粒子特效,但是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有没有办法实现
这种方法中粒子效果与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
这是一个道理, 只是有些是运行时动态算的, 我觉得尽量把脚本封装的简单易用即可。。
momo 如果 特效和UI 是 在mask 下面的话 UI的image 不会显示 这是为何 ,找了好多资料都没解决 麻烦momo帮忙看下
UI会被遮住, 但是特效 不会被遮住才对啊。。
特效是不会遮住的 我是想UI被遮住的问题 有啥解决办法么 因为UI 添加了canvas 组件后 就被遮了
mask的功能本来就是裁切啊。 mask上会记录裁切的区域。 如果mask下面的image text rawImage 大于这个裁切区域 就会自动被裁切。 如果你不想被裁切 就别放在mask下面就行了。
请问你这个问题解决了吗?
貌似isUI不管为true还是false都不影响最终效果?
运行时看, 没问题的。。
加了canvas之后点击事件捕捉不到,怎么解决?
因为没添加鼠标穿透组建所以才会:Graphic Raycaster
momo你的demo项目能发一下么 我按照你的步骤做了 但是不行
我按照步骤尝试了,但是粒子特效还是依旧显示在上方,并没有在两个界面之间
可能你做得有问题吧? 我已经用了很久了 很正常啊。。
雨松momo,可以加你Q吗?
我猜你没有把UIDepth添加到其余两个UI上
先点个赞,但是这种用法在模拟器里没问题,到手机上面就又给遮挡了
啊, 我在手机上已经用了没问题啊。
你好,请问你按照这种方法做,可以实现该效果吗?
修改renderQueue可以达到不添加摄像机,让特效在两个UI间显示
原理是一样的,NGUI以前就是用renderQueue的。。
请教用renderqueue要怎么做?
雨松大拿,真心求教个问题,加多个Canvas会对性能有多大影响呢?比如像刀塔传奇那样的游戏,都是用Stack弹出式UI,如果每一层用一个Canvas会不会有问题呢?
最好别这样。。 只有特殊情况在需要加canvas
请问为什么有两个摄像机?分别是如何使用的?
一个是UI摄像机 一个是3D摄像机。。
我也試不出來,大大能提供個範例專案嗎?
假设我要用Mesh的特效(想用他做按钮边框流光效果),要他和UI的按钮一样大小,且在按钮上面(假设这个可以解决)。当按钮自适应屏幕后,大小和位置发生了变化。那么Mesh这个GameObject怎么弄呢(把他拉到按钮的孩子里,他只会改位置,不会改大小)。
自适应不是改摄像机么? 为什么按钮还会发生变化?
感谢分享,我使用上面的代码,停止运行程序后会报以下的错误,请问该怎么解决呢m_TransformInfo.localAABB.IsValid()UnityEditor.DockArea:OnGUI()m_TransformInfo.worldAABB.IsValid()UnityEditor.DockArea:OnGUI()IsFinite(outDistanceForSort)UnityEditor.DockArea:OnGUI()IsFinite(outDistanceAlongView)UnityEditor.DockArea:OnGUI()
用4.6.3 吧 这是底层错误。。
不能用,麻烦把工程给下吧。
我的粒子系统在UGUI里面根本连显示都不显示。好像是被UGUI挡住了一样。雨凇大大,你试试移动你的粒子系统到其他位置试试?
你的粒子层要设置成UI层
你把摄像机改成正交的试试?
示例工程可以发一下不?我用的一直有问题
这个有个非常大的缺陷哎,每个在这物体上的物体都要加个UIDepth吧,而且还要加Canvas
看怎么用了。 不用给每个物体挂, 给父节点挂就行了。这种叠层需求的地方也比较少。特殊处理一下吧。。
这个方法,上下两个UGUI的图片需要在同一个CANVAS里还是两个sortingOrder不同的两个CANVAS下呢
都可以, 但是 默认order都是0 所以设置了新的order以后, 会盖在默认UI上面, 如果上面还要在弹出UI 那么就要处理order了。。
赞一个
Canvas的Render Mode得设置成Screen Space – Camera,我刚开始用的第一个无效……
刚刚开始先就UGUI,给MOMO点个赞
= =学习