Unity UI模块优化(1.原理)
来源:互联网 发布:github mac客户端下载 编辑:程序博客网 时间:2024/06/11 23:38
参考链接:https://blog.uwa4d.com/archives/1875.html,详情请点击链接查看UWA的视频解析,尊重UWA版权。本文为个人看视频学习整理笔记,同视频有删减。
NGUI VS UGUI
一.元素更新方式
1.共同点:
NGUI:
public class UIGeometry{ public BetterList<Vector3> verts = new BetterList<Vector3>(); public BetterList<Vector2> uvs = new BetterList<Vector2>(); public BetterList<Color32> cols = new BetterList<Color32>(); public BetterList<Vector3> mRtpVerts = new BetterList<Vector32>();
这个类会临时的储存顶点信息,每个UI元素,不管是UISprite还是UILabel,都有一个对应的UIGeometry对象,有几个数组存储顶点信息,如位置、法线方向、颜色等。
UGUI:
public class VertexHelper : IDisposable{ private List<Vector3> m_Positions = ListPool<Vector3>.Get(); private List<Color32> m_Colors = ListPool<Color32>.Get(); private List<Vector2> m_Uv0S = ListPool<Vector2>.Get(); private List<Vector2> m_Uv1S = ListPool<Vector2>.Get(); private List<Vector3> m_Normals = ListPool<Vector3>.Get(); private List<Vector4> m_Tangents = ListPool<Vector4>.Get(); private List<int> m_Indices = ListPool<int>.Get();
每个UI元素都有个对应的VertexHelper对象,需要UI元素的位置、长宽等信息来填充这些数组。
(所以:这些数组里东西越多,填充的过程就越长)
对制作的影响:
1/ “动态”元素(经常会改变位置或缩放或颜色的)尽量少用Outline、Tiled Sprite;
2/ 尽量减少“动态”长文本(一个Label里文字太多)
注意:
以上三种不是说尽量少用,而是说使用时:
1/ 尽量减少他们在动态元素上的使用,或者使用时候尽量保证他们是静态的,即不太会改变它的颜色、缩放等。
2/ 尽量减少这些元素所在Canvas或者UIPanel的重建,英文他们重建时会涉及到这些元素的填充。
可见,NGUI和UGUI相同点:它会转化为数组,有一个填充的过程,所以说当我们的UI元素顶点数很多,那么填充的过程时间就会很长。
2.不同点:
1/ NGUI:
UIPanel.LateUpdate:(每帧执行)
—轮询
—UIPanel.UpdateWidgets (在UIPanel.LateUpdate里每帧执行)
UpdateWidgets更新每一个激活状态的Widget的位置、状态等,有个更新和获取的过程,如果在更新过程中发现这个Widget发生了变化,那么会有一些其他的操作来引起一些开销;
即使UI们没有任何变化,轮询的开销还是会有的。所以NGUI里大的界面,就算是静态界面,也会有持续的开销。
2/ UGUI:
Canvas.SendWillRenderCanvas
—队列
—m_LayoutRebuildQueue
—m_GraphicRebuildQueue
这两个队列分别记录那些layout和Graphic发生变化的元素,界面发生变化时,会在SendWillRenderCanvas回调里rebuild这两个队列里的元素。
没有轮询的过程,所以在UGUI里静态界面相当于0消耗。
小结:
所以大量静态UI元素放在一个地方,UGUI消耗小于NGUI。
对缓存机制的影响:
动态HUD的缓冲池,如血条、伤害跳字,这些会经常批量的出现,批量的消失,我们不会说出现就实例化,消失就destroy,所以我们需要用缓存。一般我们可能会首先想到用SetActive,而UI元素这样会有额外的开销,所以我们要深入考虑。
—NGUI:
缓冲池元素适量:Color.a=0,移除 (NGUI中Scale设为0仅仅把网格scale为0,但是顶点数还在,drawcall还会提交;alaph设为0则会把顶点都去掉)
缓存池元素多:SetActive(false)
Timer +二级缓存(退出战斗后,逐渐把缓冲池里color.a=0的缓存按批禁用,于是出了战斗后缓冲池里UI不会有持续的开销)
—UGUI:
Scale = 0,Alpha Group = 0快速隐藏UI,且不会有顶点重建,不会触发激活和经验的额外开销;
在UGUI不要用Color.a=0,这个在UGUI仅仅将alaph设为0,在drawcall上是没有任何变化的,相当于贴了个透明面片,还是会画到场景里。
二.DrawCall合并规则
1.渲染顺序:
NGUI:depth
手动设置depth值,然后以UIPanel为单位,根据depth的大小做一个排序,然后相同材质的进行合并。
UGUI:hierarchy
—重叠检测
—分层合并
如右图:不同颜色为不同图集,数字为drawcall。
2.调试工具:
—NGUI:DrawCall Tool
—UGUI:Frame Debugger
3.对界面制作的影响:
—UGUI
不规则图标的摆放(实际重叠了,UGUI这里DrawCall没有办法合并)
UI元素的旋转(旋转后,如图实际上两个元素重叠了)
动态遮挡
3D UI(3D UI旋转后会发生重叠,因为是先投影到2D上)
—NGUI
手动排序
三.网格更新机制
NGUI:
UIPanel.LateUpdate 两种更新方式
-UIPanel.FillDrawCall 更新单个DrawCall
-UIPanel.FillAllDrawCalls 更新所有DrawCall
UGUI:
Canvas.BuildBatch 更新所有DrawCall
-WaitingForJob(5.2之后)
-PutGeometryJobFence(5.2之后)
-BatchRenderer.Flush*(开了多线程渲染则前两个会消失)
执行上:
如上血条+文本:
NGUI里合成后是两个mesh,会根据不同的drawcall拆分不同的网格;
在UGUI里合成后是一个mesh,2个submesh,UGUI里合并网格时,以canvas为单位,一个Canvas下所有元素会合在一个网格里,只是会分不同submesh。所以一个几何很复杂的Canvas,更新下面任何一个几何元素时,都会涉及到一个很大的dpu的修改。
对界面制作的影响:
UGUI:
拆分Canvas(动静分离)
NGUI:
控制FillAllDrawCalls
拆分UIPanel
综上: (>表示更有优势,消耗更低)
功能界面的DrawCall控制 NGUI>UGUI
功能界面的网格更新控制 NGUI>UGUI
动态HUD界面的网格更新控制 NGUI << UGUI
堆内存控制 NGUI << UGUI
- Unity UI模块优化(1.原理)
- Unity UI模块优化(2.优化渲染开销)
- Unity UI模块优化(3.优化更新开销)
- UWA六月直播第四弹-Unity UI模块优化案例精讲,今晚8点不见不散
- UWA 六月直播季 | 6.29 Unity UI模块中的优化案例精讲
- unity游戏の优化--UI
- Unity优化杂谈4(UI)
- Unity UI优化技术与技巧
- Unity UI优化技术与技巧
- Unity实战笔记_8.简单的UI框架模块间传参
- 【unity系统模块开发】Unity5.5.2UI打包AssetBundle
- Unity UI
- Android开发优化-界面UI(2)抽出公共模块
- 关于Unity的优化1.
- android UI性能优化(1)--View的工作原理
- Android高级UI-listView的原理及优化
- Unity 优化
- Unity 优化
- 2.4变动和最终变量(Volatile and Final Variables)
- springmvc数据回显(九)
- Spring注解配置定时任务<task:annotation-driven/>
- Java反射(8个)
- 上海找工作之旅
- Unity UI模块优化(1.原理)
- 【Linux】fork函数的理解
- 计算机的构造与解释(1)
- setContentView方法
- Codeforces Round #424 (Div. 2) D. Office Keys
- 练习题(队列)
- MyBatis 多对多完成版
- MyBatis多对多及一二级缓存
- PAT1019~~~