一.Unity Profiler概述
Unity Profiler 是 Unity 编辑器内置的性能分析工具。该工具能够收集
逐帧提供信息,其可监测的数据非常广泛。
可通过菜单 Window > Analysis > Profiler打开性能分析器

二.Profiler快速上手
2.1 Profiler界面构成
Profiler界面主要分为3个视图:模块控制视图,模块时间轴视图,模块详细视图:

2.2 Profiler工作流
step1:在模块控制视图中 选中要观测的模块,被选中的模块会高亮,模块详细视图会显示该模块的详细数据

step2:观测实时数据或选择一帧
以CPU Usage模块为例,在模块详细视图中打开Live开关后 可以观测实时数据(该方法不常用,需注意性能消耗)

模块时间轴视图选择一帧,此时游戏会暂停,时间轴视图选中的帧处显示白线,模块详细视图中会显示该帧的详细信息

step3:在模块详细视图中获取有用的数据,定位性能问题
由于每个模块视图中展示的数据各不相同,单个模块的模块详细视图用法将在后续章节说明
三.Profiler模块管理
3.1 模块的启用和禁用
点击Profiler Modules下拉菜单,可展开模块管理视图,可通过单选框启用禁用模块。

禁用模块会从窗口中删除该模块,停止 Profiler 收集该模块的数据,并降低 Profiler 的开销。启用 Profiler 模块时,它会开始收集数据,但在其不活动期间不显示任何数据。
**Tip:**CPU Usage模块即使在不活动时也始终会收集数据,因为其他模块依赖于它。
3.2 模块内选项(Item)的启动和禁用
模块视图中列出了该模块监视的项目。可通过点击方块启用和禁用项目,时间轴视图会同步启用的项目。对于不需要观测的项目应当禁用,可使视图更易于阅读。

3.3 模块排序
- 打开模块编辑界面
- 拖拽调整模块顺序
- 保存更改

3.4 自定义模块
可以添加自定义模块来收集指定的数据,这块先不展开,了解即可
3.5 模块详细信息资料
每个模块的详细信息可从官方文档这里找到

四.UI 和 UI Detail详细信息视图
UI 和 UI Detail 模块提供有关UGUI在布局和渲染所花费的时间和资源的信息。可使用此模块来了解 UI 批处理,以及UI模块性能较慢的原因。

| Column | Description |
|---|---|
| Object | Canvas列表 |
| Self Batch Count | Canvas的批次数量 |
| Cumulative Batch Count | Canvas和嵌套Canvas的批次数量 |
| Self Vertex Count | Canvas的顶点数量 |
| Cumulative Vertex Count | Canvas和嵌套Canvas的顶点数量 |
| Batch Breaking Reason | 合批被打断的原因 |
| GameObject Count | 批次绘制对象的数量 |
| GameObjects | 批次绘制对象的名称列表(大于1个显示数量) |
右侧有该批次绘制所有对象的预览视图

双击一行批次会选中该批次所有绘制的对象

参考:UI (Canvas) 和 UI 详细信息 (Canvas) Profiler 模块参考
五.CPU Usage详细视图
CPU Usage模块可用来获取每帧消耗的时间 以及该帧的时间如何消耗的 ,非常有助于判断性能问题的原因。
CPU Usage中的信息包括CPU相关的Item,每个Item消耗的时间,该帧的总耗时:

5.1 Timeline视图
Timeline视图展示了主线程,渲染线程,工作线程在该帧的活动情况,反应了各个任务的占用时间,下面色块是上面色块的子任务,可拖动滑块边缘 或 滚动鼠标中键缩放线程时间轴视图

时间轴的颜色对应于Item的颜色,可分辨出其所属的Item。若所选的时间轴部分是脚本执行的方法会在Hierarchy中选中对应的GameObject

Tip: 在编辑器里运行游戏时,EditorLoop 的开销会附加到每一帧中,导致 Profiler 中显示的 Others 类别占比虚高,这个时间在最终发布的游戏包体里不存在。
理解Player Loop和Editor Loop:
Player Loop:游戏打包后的运行环境(Player)中的主循环。它负责按照固定顺序处理输入、物理、渲染、脚本逻辑等。
Editor Loop:Unity Editor 环境下的主循环,用来驱动场景视图、Inspector 刷新、脚本编译、播放模式切换、Gizmos 渲染等编辑器功能,仅在编辑器中运行才会有Editor Loop.

时间轴上的色块叫做Instance(实例),选中一个实例,会弹出一个窗口,其展示了该实例执行的时间,以及本帧中有多少个实例,所有实例执行的时间:
5.2 Hierarchy视图
| Property | Function |
|---|---|
| Total | 该函数及子函数花费总时间在该帧的百分比 |
| Self | 该函数自身(不包括子函数)花费时间在该帧的百分比 |
| Calls | 此帧中对此函数的调用次数。在原始层次结构视图中,此列中的值始终为 1 |
| GC Alloc | 该函数分配的堆内存 |
| Time ms | 该函数及子函数花费总时间(ms) |
| Self ms | 该函数自身(不包括子函数)花费总时间(ms) |
单机任意一列标题可对其进行排序
一个函数的Time(ms) = 其Self(ms) + 子项的Time(ms)

RelatedData视图:点击一行可在Hierarchy视图中看到该方法由哪个GameObject调用

Calls视图:展示该函数调用的子函数以及被哪个函数所调用

[Invoke]标记:表示该函数是项目脚本中的手写函数(不是引擎API)

5.3 Raw Hierarchy视图
Raw Hierarchy和Hierarchy视图的区别是其方法不会进行合并

