Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽

前言:拼UI相信每个Unity程序都做过的事,也是普遍认为最简单、最入门、最没有技术的工作。不出意外的情况下,都会做出策划需要的效果,但是功能实现了,真的就是正确的吗?或者说真的就是合理的吗?那就不一定了。

Unity的优化不简单的归咎于改一行代码,更改一个参数或者勾选一个选项就会发生质的变化,如果真的是这样,无非两种,官方出了新的功能,或者在开发中有很不合理的地方。

优化的本质其实就是本着能省就省,量身定做,只有保持匠心精神,成系统的优化,才能在性能上有优异的表现。从资源(图片,模型等)进到工程到的那一刻起,就应该保证他是符合规范或者可控,只有在层层的有规范的检查下,才能最大限度保证出包的品质和减少无谓的加班~~~

只有把地基打好,才能稳定层层叠加,下面是笔者整理关于拼UI相关的注意事项,希望能够帮到大家

其他优化点会陆续添加


有说的不正确或者不准确的地方欢迎留言指正


主要参考如下:

  • 侑虎科技
  • 官方UGUI最佳优化技巧--自备梯子
  • 雨松MOMO
  • 钱康来

Unity版本 2018.4.0f1

示例工程下载

准备工作,先打开Sprite Packer中的Mode

如果要 Sprite Atlas合批设置成 Always Enabled (Legacy Sprite Packer)

image.png

1. 设置图集的图片可以合批
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第1张图片
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第2张图片
2. 避免不同图集或材质的倾轧,Scene视图调节为Writeframe模式可以更容易查看
3. 倾轧时,在Hierarchy视图中排序错误,导致合批的步骤增加
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第3张图片

Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第4张图片

Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第5张图片
4. Mask会增加一个Draw,并且Mask里面的图片不会和外面的图片合批
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第6张图片

Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第7张图片
5. RichText会造成三角面增加

6. 空的Image造成一个Drawcall并且会打断合批
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第8张图片

7. 颜色渐变和可以用material控制,本质是更改Tint属性,这样既能满足颜色渐变,又能避免网格频繁重建造


8. 接受射线脚本:Empty4Raycast

使用的此脚本可以在有效接受点击事件的情况下,不增加drawcall和打断合批


9. 减少OverDraw脚本:PolygonImage
10. 关闭不需要的Raycast Target选项(Image、Text、RawImage),降低每帧检测射线的性能消耗。检测勾选Raycast Target脚本 :DebugUILine
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第9张图片
11. 用多个Canvas将屏幕划分出不同的区域,降低网格重建带来的性能损耗
12. 避免或者降低赋值的操作,降低网格重建频率 例如在Update中执行textComponent.text = "菜鸟海澜",如果数值没有变化可以不用赋值,有变化一秒赋值一次
13. 避免使用Blocking Objects来遮挡射线,因为这是一个相当消耗性能的操作
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第10张图片
14. Screen Space 和 World Space 中的Camera必须要指定,负责会每帧7-10次调用Object.FindObjectWithTag!!!
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第11张图片

15. Layout这种东西少用,或者用了尽可能减少子节点的变动,(让结构简单点也行)因为会从变动节点递归向上调用GetComponents,而且要最大可能减少嵌套Layout。(不过没有开发时间还是用吧~~~)


16. Canvas下面的UI元素移动到屏幕外很远处,会分情况出现Drawcall数量变动的情况
  • Screen Space -Camera模式下移除全部UI会引起Drawcall的变化
  • Screen Space - Overlay模式下移除全部UI不会引起Drawcall的变化
  • 但是这两种模式只移除部分UI(图片部分)并不会引起Drawcall的变化
  • 而且在UI移动后会影响原来的Depth排序,造成合批失败产生更多的Drawcall

17. 频繁需要SetActive的物体可以使用Canva Group组件,可以有效降低重建消耗
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第12张图片
18. 禁用Canvas组件本身可以避免重建消耗来达到隐藏的效果(前提节点没有改变),但是对应脚本上的OnEnable、OnDisable会触发,所以笔者一直用Canva Group组件
19. outline和shadow组件就不要用了,Text Mesh Pro性能更好,功能强大,还免费!!!
20. Frame Debug真是一个好工具,可以有效查看渲染顺序和不能合批的原因
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第13张图片

21. 配合Profiler中新添加的UI性能监控真是锦上添花

22. Scroll Rect 组件对应的Content填加 Canvas 组件 ,因为对应的Mask 子元素依然参与全局的Depth排序,避免因拖动打乱原有的Depth排序,造成合批失败

Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第14张图片
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第15张图片

23. 用户协议等巨型篇幅的文字显示,会造成Canvas.sendWillRenderCanvases 开销过大。因为内容过大,导致vertexhelper中的list的capacity过大,基本的clear操作都会非常耗时,所以用反射调用每个List的TrimExcess函数,如果反射不熟悉的同学请看Unity C#基础之 反射反射,程序员的快乐

下面为UGUI部分源码

Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第16张图片

24. 降低使用字体的种类。字体Font资源需要单独打包,否则会造成字体被重复打包到对应的UI Bundle里面。

25. Mask 与 Rect Mask 2D 的区别

建议按照实际需求进行权衡

  • Rect Mask 2D
    • 节省 DrawCall 和 Overdraw
    • 增加 Cull 开销(Canvas.SendWillRenderCanvases())
      • 持续开销较低
      • 拖动时开销较高
Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽_第17张图片
Mask
Mask
Rect Mask 2D

你可能感兴趣的:(Unity 之 UGUI优化(Optimizing UGUI)---当最专业的拖拖拽拽)