1、应用程序性能分析
帧率:单位FPS,是衡量游戏性能的标准。
渲染:绘制一帧到屏幕被称为渲染一帧。
每帧花费时间=1000/[渴望的帧率]
1.1 三种方式
在目标平台上的播放器中对应用程序进行性能分析
在Unity编辑器中以运行模式对应用程序进行性能分析
对Unity编辑器进行性能分析
1.2 三种方式区别
获得有关应用程序的准确时序的最佳方法是在打算发布它的终端平台上对它进行性能分析。
缺点:每次改进应用程序的性能元素时都需要重新构建一次,非常耗时。
要快速评估应用程序的性能,采用直接在Unity编辑器中以运行模式对应用程序进行性能分析。
缺点:在运行模式下进行性能分析不会准确反映应用程序在真实设备上表现出的性能,但它是一个有用的工具,可在终端平台上进行初始分析后快 速检查进行的更改是否可提高应用程序的性能。
单独对Unity编辑器进行性能分析以确定它使用的资源。Unity 编辑器可能会影响应用程序的性能,因为它在运行模式下运行时使用与应用程序相同的资源。更适用于应用程序仅设计为在运行模式下工作(例如用于电影制作)。
1.3 相关设置(通用)
当启用Development Build 设置,与性能分析器相关的以下两个设置将变为可用状态:Autoconnect to Profiler 和 Deep Profiling Support。这两个设置可以按照需求设置。
Autoconnect to Profiler:Unity编辑器在构建过程中将自己的IP地址烘培到已构建的播放器中。播放器启动时会尝试连接到位于所烘培IP地址的编辑器中的性能分析器。
Deep Profiling Support:Unity会在构建的播放器启动时执行深度性能分析,即对代码的每个部分(精确到函数接口)进行性能分析。可以获取有关应用程序启动时间的深度性能分析信息,但会为构建增加开销。
注意:如果要将深度性能分析用于Android构建,必须启用 Android Player Settings 中的 Mono Scripting Backend 设置(菜单:Edit > Project Settings > Player > Android > Other Settings),这个选项默认是勾选的。然后通过 adb 命令(有待验证是否必要)来启动游戏
adb shell am start -n {insert bundle identifier here}/com.unity3d.player.UnityPlayerActivity -e ‘unity’ ‘-deepprofiling’
1.4 在Android平台上对应用程序进行性能分析(方法一,主要方法)
通过 WiFi 或通过 Android Debug Bridge (adb)。
1.4.1 通过WIFI性能分析
在车机上禁用移动数据。
使用网线将车机连接到计算机。性能分析器会使用本地网络将性能分析数据从设备发送到 Unity Editor。打开Build Setting界面(File→ Build Settings),选择Android平台。启用Development Build 设置。启用后,与性能分析器相关的以下两个设置将变为可用状态:Autoconnect to Profiler 和 Deep Profiling Support(看情况选用)。启用Autoconnect to Profiler 设置,然后选择 Build & Run。
当应用程序在车机上启动时,打开Profiler窗口(Window→ Analysis→ Profiler)
注意:Android 设备和主机(运行 Unity 编辑器)必须位于同一子网上才能正常进行设备检测。
1.4.2 Android Debug Bridge (adb) 性能分析
通过USB连接计算机和车机,车机进入工程模式→ USB模式切换,点击host切换到显示peripheral
打开 Build Settings(菜单:File > Build Settings),选中 Development Build 复选框,然后选择 Build & Run。
应用程序在车机上启动时,请在 Unity 编辑器中打开 Profiler 窗口(菜单:Window > Analysis > Profiler)。 从 Attach to Player 下拉菜单中,选择 AndroidProfiler(ADB@127.0.0.1:34999)。
如果要将深度性能分析用于Android构建,必须启用 Android Player Settings 中的 Mono Scripting Backend 设置(菜单:Edit > Project Settings > Player > Android > Other Settings),这个选项默认是勾选的。然后通过 adb 命令来启动游戏
adb shell am start -n {insert bundle identifier here}/com.unity3d.player.UnityPlayerActivity -e ‘unity’ ‘-deepprofiling’
1.5 在Unity编辑器中进行性能分析(方法二)
在编辑器中进行性能分析时,都应确保在最大化视图中打开运行模式,并减少打开的编辑器窗口的数量。这可确保其他编辑器窗口不会在渲染线程和 GPU 上耗尽时间,而会以更接近目标设备的分辨率运行应用程序。
在Unity编辑器中点击运行应用程序,然后打开Profiler 窗口(菜单:Window > Analysis > Profiler),从 Attach to Player 下拉菜单中选择Playmode
1.6 对编辑器进行性能分析(方法三)
将性能分析器的目标更改为Editor
1.7 独立性能分析器
打开独立性能分析器(Window > Analysis > Profiler(Standalone Process))。使用独立性能分析器可以减少Profiler窗口对编辑器性能的影响,适用于将编辑器作为性能分析目标以及对应用程序进行深度性能分析。
2、常见性能分析器标记
Unity的代码配备了大连性能分析器标记,用于深入了解应用程序中占用时间的内容。ProfilerRecorder 也可以使用这些标记来获取主线程上帧的时间使用情况。
常见的标记:主线程基础标记、脚本更新标记、渲染和VSync标记、后端脚本标记、多线程标记、物理标记、性能警告。
2.1 主线程基础标记
可清晰区分在应用程序上花费的时间与在编辑器和性能分析器活动中花费的时间。最需要关注的是 PlayerLoop 方法。这是 Unity 的主循环,该循环中的代码每帧运行一次。
PlayerLoop
包含源自应用程序主循环的所有样本。当播放器以活跃运行模式在编辑器中运行时,目标是编辑器(Edit)而不是运行模式(Playmode),则PlayerLoop样本会嵌套在EditorLoop下。
EditorLoop
包含源自编辑器主循环的所有样本。仅当在Editor中对播放器进行性能分析时才会出现此样本。使用性能分析器将运行模式作为目标时,EditorLoop样本会显示渲染和运行包含播放器的编辑器所花费的时间。
性能分析器不会在 EditorLoop 标记下记录任何进一步的详细数据。这是因为性能分析器在对运行模式进行性能分析时,编辑器代码发出的样本会产生大量性能分析开销。
Unity 将来自 EditorLoop 标记的任何样本都在 CPU 分析器模块图表中分类为 Others。因此,EditorLoop 样本通常是该类别的最大贡献者。如果想了解编辑器在这段时间内的操作,并且还想获得有关 Others 类别的其他贡献者的更详细细分,请将性能分析器目标更改为编辑器。
将性能分析器的目标切换为编辑器会更改性能分析器在 CPU 性能分析器模块的详细信息面板中显示的内容,以及 CPU 性能分析器模块图表中的类别细分。这是因为之前隐藏在 EditorLoop 样本下的样本随后会归类到其各自的类别中。
Profiler.CollectEditorStats
包含与收集不同活跃性能分析器模块的统计信息有关的任何样本。
嵌套在 Profiler.CollectGlobalStats 标记下的样本指示播放器在收集特定模块的统计信息时产生的开销量。所有其他子样本仅反映它们在编辑器中的效果。
要消除特定模块产生的开销,请关闭模块的图表,或调用 Profiler.SetAreaEnabled。
注意:使用内置计数器的自定义性能分析器模块会启用内置计数器的区域(即使它所属的模块已禁用)。要防止性能分析器收集这些统计信息和产生收集开销,请确保禁用内置性能分析器模块和自定义性能分析器模块。
目标是编辑器:
目标是运行模式:
2.2 脚本更新标记
除非使用作业系统,否则大多数脚本代码都嵌套在以下标记下面。如果已通过 PlayerLoop.SetPlayerLoop 将自己的回调插入到播放器循环中,则脚本更新样本会出现在相应的主 PlayerLoopSystem 标记下(如果作为子系统进入,或者如果自行直接进入主循环中)。
标记 | 功能 |
---|---|
BehaviourUpdate | 包含 MonoBehaviour.Update 方法的所有样本。 |
CoroutinesDelayedCalls | 包含首次生成后的所有协程样本。 |
FixedBehaviourUpdate | 包含 Monobehaviour.FixedUpdate 方法的所有样本。 |
PreLateUpdate.ScriptRunBehaviourLateUpdate | 包含 Monobehaviour.LateUpdate 方法的所有样本。 |
Update.ScriptRunBehaviourUpdate | 包含所有 MonoBehaviour.Update 和协程样本。 |
2.3 渲染和VSync标记
这些标记包含 CPU 在其中花时间来处理 GPU 的数据,或者可能在其中等待 GPU 完成的样本。这些标记下的样本可用于很好地了解应用程序是 CPU 限制型还是 GPU 限制型。
WaitForTargetFPS
指示应用程序等待 Application.targetFrameRate 指定的目标 FPS 所花费的时间量。
如果样本是 Gfx.WaitForPresentOnGfxThread 的子样本,则指示应用程序等待 GPU 所花费的时间量。
要确定导致带有此标记的样本使用大量时间的原因,请切换到 CPU 性能分析器模块中的 Timeline 视图。在此视图中,可以检查渲染线程上发生的情况,以及在当前帧中结束的此样本与在周围帧中结束的相同样本之间所经过的时间量。
如果持续时间大于应用程序帧时间(基于目标帧速率或 vSync),则帧渲染或计算时间过长。如果是这种情况,请调查渲染线程,并查看相对于它为做好准备和向 GPU 发出命令而进行的其他工作,它在 Gfx.PresentFrame 方面花费的时间量。如果渲染线程在 Gfx.PresentFrame 方面花费了大量时间,则渲染工作是 GPU 限制型。如果渲染线程的时间花费在准备命令上,则应用程序是 CPU 限制型。
注意:编辑器不在 GPU 上进行 VSync,而是使用 WaitForTargetFPS 模拟 VSync 的延迟。某些平台(尤其是 Android 和 iOS)强制执行 VSync 或默认帧率上限为 30 或 60。
Gfx.PresentFrame
表示应用程序在等待 GPU 渲染和呈现帧方面花费的时间,其中包括等待 VSync 的时间。
主线程上带有 WaitForTargetFPS 标记的样本会显示等待 VSync 所花费的时间量。
Gfx.ProcessCommands
包含对渲染线程上渲染命令的所有处理。应用程序可能会花费此处理时间的一部分来等待 VSync 或主线程的新命令;可通过子样本 Gfx.WaitForPresentOnGfxThread 来了解此内容。
Gfx.WaitForCommands
指示渲染线程已准备好接受新命令。如果看到此标记,则可能指示主线程上存在瓶颈。
GraphicsAPIName.WaitForLastPresent e.g.
GfxDeviceD3D11.WaitForLastPresent
GfxDeviceD3D12.WaitForLastPresent
GfxDeviceMetal.WaitForLastPresent
当主线程等待 GPU 将帧号翻转到屏幕 (Time.frameCount - QualitySettings.maxQueuedFrames + 1`) 时,会出现带有此标记的样本。这意味着如果 QualitySettings.maxQueuedFrames 大于 1,则此时间用于等待 GPU 翻转应用程序在前一个主线程帧中请求渲染的帧。
Gfx.WaitForPresentOnGfxThread
指示主线程已准备好开始渲染下一帧,但是渲染线程未结束对于 GPU 呈现该帧的等待。这可能表明应用程序是 GPU 限制型。要查看渲染线程同时在哪些方面花费时间,请查看 CPU 性能分析器模块的 Timeline 视图。
如果渲染线程将时间花费在 Camera.Render 中,则表示应用程序为 CPU 限制型并且可能花费太多时间向 GPU 发送绘制调用或纹理。
如果渲染线程将时间花费在 Gfx.PresentFrame 中,则表示应用程序是 GPU 限制型,或者可能在等待 GPU 上的 VSync。Gfx.WaitForPresentOnGfxThread 的 WaitForTargetFPS 子样本可以指示应用程序用于等待 VSync 的呈现阶段的一段时间。呈现阶段是从 Unity 指示图形 API 交换缓冲区到此操作完成时间之间的一段时间。
Gfx.WaitForRenderThread
指示主线程正在等待渲染线程处理位于命令流中的所有命令。带有此标记的样本仅出现在多线程渲染中。
2.4 后端脚本标记
突出显示 Mono 或 IL2CPP 脚本后端活动,对于垃圾收集和分配问题的故障排除非常有用。
GC.Alloc
表示托管堆(包含受自动垃圾回收影响的托管分配)中的分配。要减少应用程序在自动垃圾收集方面所花费的时间,应该尽量减少这些类型的样本。
GC.Collect
表示与垃圾收集相关的样本。每当 Unity 需要执行垃圾收集时,它都会停止运行程序代码,并且仅在垃圾回收器完成所有工作后才恢复正常执行。注意:如果启用了增量垃圾收集,则垃圾回收器可能不会在单个帧内完成其工作。
此中断可能会导致应用程序执行出现延迟,从不到一毫秒到数百毫秒不等。这取决于垃圾回收器需要处理的内存量以及应用程序运行的平台。
Mono.JIT
仅限 Mono 包含与脚本方法的即时编译相关的样本。当函数首次执行时,Mono 会编译它,Mono.JIT 表示此编译开销。
UnsafeUtility.Malloc
包含调用 UnsafeUtility.Malloc 以分配非托管内存的样本。虽然垃圾回收器不跟踪此内存,但分配内存可能会产生显著性能影响(随此样本出现)。要调查此调用的源,可以在 Profiler 窗口中为此标记启用调用栈记录。
2.5 多线程标记
不测量消耗的 CPU 周期,而是突出显示与线程同步和作业系统相关的信息。要查看以下标记时,需要使用 CPU 性能分析器模块的 Timeline 视图检查其他线程上同时发生的操作。
Idle
包含指示工作线程处于非活动状态的时间长度的样本。工作线程在作业系统不使用它的任何时间都处于非活动状态,会进入等待模式以等待信号标。
Idle 样本之间的小间隙通常发生在作业系统唤醒它们时(例如用于安排新作业)。较长的间隙可能指示尚未检测的本机作业在线程上运行。
JobHandle.Complete
包含指示作业同步点何时发生的样本。同步点可能会对应用程序产生性能影响,并可能会干扰多线程作业代码的执行。要更容易找到同步点发生的确切位置,请为此样本启用调用栈记录。在 CPU 性能分析器模块的 Timeline 视图中,可以启用 Flow Events 以查看此时完成的作业。
Semaphore.WaitForSignal
包含描述线程上的同步点的样本。要找出所等待的线程,请在 Timeline 视图中查看在此线程之前不久结束的所有样本。
WaitForJobGroupID
触发了 JobHandle 上的同步栅栏 (Sync Fence)。这可能导致工作窃取。一个工作线程完成工作,然后等待其他工作线程完成工作时,就会发生工作窃取。这些显示为在此标记下执行的作业样本。“被窃取”的作业不一定是所等待的作业。
2.6 物理标记
下表概括了一些高级物理性能分析器标记。FixedUpdate 会调用所有这些测量。
Physics.FetchResults
包含从物理引擎收集物理模拟结果的样本,例如接触流、触发器重叠和关节断裂事件。
Physics.Interpolation
包含测量 Physics.Interpolation 方法的执行时间的样本。此方法管理应用程序中所有物理对象的位置和旋转的插值。
Physics.Processing
包含花费时间等待主线程直到物理模拟在所有线程上完成的样本。如果应用程序在 Physics.Processing 方面花费大量时间,但是在场景中只有几个与物理相关的游戏对象,这可能指示工作线程由于工作窃取而拾取了其他系统任务并报告为物理。这是因为在等待期间,主线程会从高优先级队列中拾取作业。
Physics.ProcessingCloth
包含测量 Physics.ProcessingCloth 方法的执行时间的样本。此方法处理所有布料物理作业。展开此样本可显示物理引擎内部完成的工作的低级细节。
Physics.ProcessReports
包含与通过回调(如 OnTriggerEnter)将物理数据转发到脚本所花费的时间相对应的样本。注意:这些样本不计算所需的数据,因为它们已经在 FetchResults 期间做好准备。
有四个不同的子阶段:
Physics.Contacts
包含测量 Physics.Contacts 的执行时间的样本。这会处理 OnCollisionEnter、OnCollisionExit 和 OnCollisionStay 事件。
Physics.JointBreaks
包含测量 Physics.JointBreaks 的执行时间的样本。这会处理与受损关节相关的更新和消息。
Physics.TriggerEnterExits
包含测量 Physics.TriggerEnterExits 的执行时间的样本。这会处理 OnTriggerEnter 和 OnTriggerExit 事件。
Physics.TriggerStays
包含测量 Physics.TriggerStays 的执行时间的样本。这会处理 OnTriggerStay 事件。
Physics.Simulate
包含测量为 Physics.Simulate 方法处理先决条件所花费的时间量的样本。此方法指示物理引擎运行其模拟,这会更新当前物理的状态。
Physics.UpdateBodies
包含更新所有物理体的位置和旋转的样本。对于每个具有刚体组件的游戏对象,带有此标记的样本会从物理引擎读取姿势并将其写入变换组件。
Physics.UpdateCloth
包含测量 Physics.UpdateCloth 方法的执行时间的样本。此方法处理与布料及其蒙皮网格相关的更新。
2.7 性能警告
CPU 性能分析器可检测到一些常见性能问题,并发出相关警告。这些警告会显示在 CPU 性能分析器模块的模块详细信息面板 Hierarchy 视图中的 Warning 列内。
性能分析器可以检测到在性能至关重要的背景中应避免的某些特定调用。这种情况下会显示警告以及操作对性能产生影响的原因,如下所示:
Animation.DestroyAnimationClip
Animation.AddClip
Animation.RemoveClip
Animation.Clone
Animation.Deactivate
指示已触发 RebuildInternalState。RebuildInternalState 是一种操作,它遍历动画组件中每个剪辑的曲线列表,然后将每条曲线重新绑定到游戏对象上某个组件中的值。
这是一种资源密集型操作,因此应尽可能避免在运行时调用这些方法。
AssetBundle.asset/allAssets
指示在 AssetBundle 加载未完成时(AssetBundleRequest.isDone 为 false),Unity 调用了 AssetBundleRequest.assets/allAssets API。这会导致主线程卡顿并等待加载操作完成。
AsyncUploadManager.AsyncBufferResized
AsyncUploadManager.AsyncBufferDelete
指示用于将数据上传到 GPU 的内部缓冲区调整了大小,因为它不够大。这种大小调整比较缓慢,会导致 CPU 活动出现峰值。
如果可以腾出内存来提前分配较大的大小,则可以避免此警告。
可以使用质量设置中的 Async Upload Buffer Size 设置默认大小。
AsyncUploadManager.AsyncBufferResized 标记指示新分配的大小,可以将其用作默认缓冲区大小的指南。
Rigidbody.SetKinematic 为刚体重新创建非凸面体 MeshCollider。
3、Profiler窗口
3.1 Profiler首选项
打开Profiler首选项界面,Edit→ Preferences→ Profiler
Frame count:设置性能分析器要捕获的最大帧数。可以将此数字设置在 300 到 2,000 之间。
Show stats for ‘current frame’:默认情况下,选择 Current Frame 按钮并进入 Current Frame 模式时,帧指示线不会随当前帧统计信息显示相关注释。这是因为统计信息注释可能导致难以实时查看数据。要显示注释,请启用此设置。
Default recording state:默认选择Enabled,选择性能分析器应该在哪种记录状态下打开。可选择 Enabled、Disabled 或 Remember。Enabled 保持 Record 按钮在会话之间启用,而 Disabled 则将其禁用,无论在性能分析会话期间是否将其打开或关闭。Remember 状态会记住您是否启用或禁用了 Record 按钮,并在下次打开 Profiler 窗口时保持其上次的状态。
Default editor target mode:默认选择选择 Playmode ,Attach to Player 下拉选单的默认目标模式。可选择 Playmode 或 Editor。
3.1 Profiler窗口布局
A:性能分析器模块。这是可以在应用程序中接受性能分析的所有模块的列表。此区域顶部的下拉菜单可以在窗口中添加和删除模块。
B:性能分析器控件。使用这些控件可以设置要从哪个设备进行性能分析以及 Unity 应该执行哪种性能分析,可以在帧之间进行导航,还可以开始记录数据。
C:帧图表。此区域包含性能分析器进行性能分析的每个模块的图表。首次打开性能分析器时,该区域为空白;开始对应用程序进行性能分析时,该区域中将填充信息。
D:模块详细信息面板。此窗口区域中的信息根据所选择的模块而异。例如,选择 CPU Usage Profiler 模块时,此区域包含详细的时间轴和切换到 Hierarchy 视图的选项。选择 Rendering Profiler 模块时,此区域显示调试信息列表。首次打开性能分析器时,该区域为空白;开始对应用程序进行性能分析时,该区域中将填充信息。
3.1.1 性能分析器控件
Attach to Player : 选择对应用程序进行性能分析时所针对的目标。默认设置为 Playmode。也可以选择 Editor 以对 Unity Editor 进行性能分析并显示 Editor 当前在使用的资源。Unity 还自动检测网络上正在运行或通过 USB 连接的所有设备,并将这些设备显示在下拉选单中。单击下拉选单中的 Enter IP 可手动输入设备的 IP 地址,以便在该设备上对应用程序进行性能分析。
Record : 启用此设置可以在运行应用程序时记录活跃模块的性能分析信息。如果未启用此按钮,则在运行应用程序时,性能分析器不会收集任何数据。
Back arrow : 向后导航一帧。
Forward arrow : 向前导航一帧。
Current Frame : 单击 Current Frame 按钮时,帧指示线会跳到最后记录的帧,并且性能分析器进入 Current Frame 模式。性能分析器在此模式下收集数据时,它会停留在当前帧上并实时显示收集的数据。再次单击该按钮将退出 Current Frame 模式。
Frame number : 指示当前在性能分析器中查看的帧的编号。左边的数字是当前选择的帧,右边的数字是性能分析器在整个分析会话期间收集的总帧数。
Clear : 从 Profiler 窗口擦除所有数据。
Clear on Play : 启用此设置后,下次单击 Player 窗口中的 Play 或连接到新的目标设备时,可从 Profiler 窗口擦除所有数据。
Deep Profile : 启用此设置可对所有 C# 方法进行性能分析。启用此设置后,Unity 会将检测功能添加到所有 Mono 调用,然后便可以对脚本进行更详细的调查。即启用深度性能分析。
Call Stacks : 要记录用于脚本内存分配的调用栈,请单击此开关。启用此选项时,性能分析器记录的帧包含所选样本在完整调用栈的信息;即使在 Deep Profile 未激活的情况下,完整调用栈上的这些样本也会导致托管脚本分配。默认情况下,启用此设置时性能分析器记录 GC.Alloc 样本的完整调用栈信息 ,但您可以从下拉菜单中将其更改为另一个样本(UnsafeUtility.Malloc、JobHandle.Complete 或 Native Allocations)。
Load : 将已保存的性能分析器数据加载到 Profiler 窗口中。还可以加载播放器通过 Profiler.logFile API 写出到文件的二进制性能分析数据。按住 Shift 按钮并单击 Load 按钮可将文件内容附加到当前性能分析帧。
Save : 将性能分析器数据保存到 Project 文件夹中的 .data 文件中。
上下文菜单:
Color Blind Mode : 启用此设置可使性能分析器在其图形中使用更高对比度的颜色。这样可以增强红绿色盲(例如绿色盲、红色盲或蓝色盲)用户的视觉感知度。
Show stats for “current frame”: 默认情况下,选择 Current Frame 按钮并进入 Current Frame 模式时,帧指示线不会随当前帧统计信息显示相关注释。这是因为统计信息注释可能导致难以实时查看数据。要显示注释,请启用此设置。
Preferences : 打开 Preferences 菜单以调整特定于性能分析器的属性。
3.1.2 性能分析器模块
可以在Profiler Modules选择对特定方面进行性能分析。
CPU Usage 模块最能够体现应用程序在每帧中花费的时间。其他模块收集更具体的数据,有助于检查更具体的方面或监测应用程序的重要信息,例如内存消耗、渲染或音频统计信息。
每个模块都有自己的图表。选择模块时,模块详细信息面板将显示在窗口的底部,可用于检查该模块收集的详细数据。
还可以更改图表中类别的顺序,可以在图表的图例中拖放这些类别。还可以单击某个类别的有色图例以切换是否显示。
性能分析器模块 | 功能 |
---|---|
CPU Usage | 概要显示应用程序在哪些方面花费最多时间(涉及物理、脚本、动画和垃圾收集等多个方面)。该模块包含有关应用程序的大量性能分析信息,您可以使用这些信息来决定进一步使用哪些其他模块来调查应用程序中的更具体问题。该模块始终处于激活状态(即使您将其关闭)。请参阅 CPU Usage Profiler 模块 |
GPU Usage | 显示与图形处理有关的信息。默认情况下,此模块处于非激活状态,因为它的开销较大。请参阅 GPU Usage Profiler 模块。 |
渲染 | 显示有关 Unity 如何在应用程序中渲染图形的信息,包括有关静态和动态批处理、SetPass 和 Draw 调用、三角形和顶点的信息。请参阅 Rendering Profiler 模块。 |
Memory | 显示有关 Unity 如何在应用程序中分配内存的信息。这尤其适合用于查看脚本分配 (GC.Alloc) 如何引起垃圾收集或者是应用程序的资源内存使用量随时间变化的趋势。请参阅 Memory Profiler 模块。 |
Audio | 显示应用程序中的音频相关信息,例如何时播放音频源以及播放的音频源数量、音频系统需要的 CPU 使用率以及 Unity 为其分配的内存量。请参阅 Audio Profiler 模块。 |
Video | 显示应用程序中的视频相关信息。请参阅 Video Profiler 模块。 |
Physics | 显示应用程序中物理引擎已进行的物理处理的相关信息。请参阅 Physics Profiler 模块 |
Physics (2D) | 与 Physics Profiler 模块类似,此模块显示应用程序中物理引擎已进行的 2D 物理处理的相关信息。 |
UI | 显示有关 Unity 如何为应用程序处理 UI 批处理的信息,包括 Unity 为何以及如何对项目进行批处理 |
UI Details | 与 UI 模块类似,此模块的图表添加有关批处理和顶点计数的数据,以及标记(包含有关触发 UI 变化的用户输入事件的信息)。 |
GlobalIllumination | 显示有关 Unity 在应用程序中的全局光照 (Global Illumination) 光照子系统中花费的 CPU 资源的信息。 |
Virtual Texturing | 显示有关您的应用程序中串流虚拟纹理的统计信息。。 |
3.1.3 模块详细信息面板
每个性能分析器模块的都不一样,需要按模块看。
3.1.4 CPU Usage Profiler 模块
CPU Usage Profiler 模块的图表可跟踪应用程序主线程中花费的时间。
图标类别
这些时间被分为九个类别,如下表所示:
Rendering 应用程序花费多少时间来渲染图形。
Scripts 应用程序花费多少时间来运行脚本。
Physics 应用程序在物理引擎上花费多少时间。
动画 应用程序花费多少时间来动画化应用程序中带蒙皮的网格渲染器 (Skinned Mesh Renderers)、游戏对象和其他组件。这还包括针对 Animation 组件和 Animator 组件所用的系统进行计算所花费的时间。
GarbageCollector 应用程序花费多少时间来运行垃圾回收器
VSync 应用程序每帧花费多少时间来等待 targetFrameRate 或下一个要同步的 VBlank。此时间基于 QualitySettings.vSyncCount 值、目标帧率或者 VSync 设置(即运行应用程序的平台的默认或强制最大值)
Global Illumination 应用程序在光照中花费多少时间。
UI 应用程序花费多少时间来显示其 UI。
Others 应用程序在不属于任何其他类别的代码中花费多少时间。此事件包括整个 EditorLoop 或者是 Editor 中对运行模式进行性能分析时的性能分析开销等方面。
模块详细信息面板
有三个可用视图,如下表所示:
Timeline 显示特定帧的时间细分信息,以及该帧长度的时间轴。只有在此视图模式中才可以一次性查看所有线程上的时间以及在帧内运行线程的时间,因此可以关联各个线程的时间。
Hierarchy 按时间数据的内部层级结构对这些数据分组。此选项以降序列表格式显示应用程序调用的元素,默认按花费的时间排序。还可以按分配的脚本内存量 (GC Alloc) 或调用次数对信息进行排序。要更改用于对表进行排序的列,请单击该表列的标题。
Raw Hierarchy 以类似于发生计时的调用栈的层级结构显示时间数据。Unity 在此模式中单独列出每个调用栈,而不是像在 Hierarchy 视图中一样将它们合并。
Hierarchy 视图列出已进行性能分析的所有样本,并按共享的调用栈和 ProfilerMarker 层级视图将样本一起分组。Raw Hierarchy 视图不会将样本一起分组,因此非常适合在粒度级别上查看样本。也可以使用 Thread 下拉选单来选择特定线程,例如要在这些视图中检查的主线程 (Main Thread) 或渲染线程 (Render Thread)。
注意:“GC Alloc”列不能用于统计主线程(比如用户创建的线程)之外发生的托管分配。
“GC Alloc”列:此列显示了在特定帧中的托管堆上分配的字节数,使用 Unity 的深度性能分析 (Deep Profile) 模式可找到托管分配的具体方法。
Live设置
当您开始在运行模式 (Playmode) 或 Editor 中记录新数据时,Live设置(在每个视图中都可用)可在模块详细信息面板中显示有关当前帧或选定帧的信息。为了启用此设置,请单击模块详细信息下拉选单旁的 Live 按钮。默认情况下,此设置已禁用,并且在您记录数据时模块详细信息面板为空白。
注意:重绘 Profiler 窗口时,此设置会增加 EditorLoop 的开销。
Show Full Scripting Method Names
在每个视图中,可以选择 More Items 菜单 (⋮) 并启用Show Full Scripting Method Names,此设置随后显示所有脚本方法的完全限定名称 (Assembly::Class::MethodName)。
Flow Events(Timeline视图独有)
直观地展示了Unity如何跨线程调度作业。启用该设置后,性能分析器会将白色事件标记添加到用于调度作业或等待调度作业完成的性能分析器样本。它还会使不相关的样本变暗,以便更容易地看到选择的样本。
性能分析器将三种类型的箭头添加到样本中:
向下箭头:指示流程的开始,并且此样本调度了某些工作。
向右箭头:指示流程中的下一个项目,并且另一个样本调度了此工作。
向上箭头:指示流程的结束,以及此样本上的工作已结束或同步。
当选择一个样本时,Profiler 将相关的流程事件标记用线条连接在一起。粗线条突出显示选择的特定流程。例如,如果一个 begin 样本指向另外两个 next 样本,当单击 next 样本之一时,性能分析器会为其绘制一条较粗的线条。
此视图有助于发现代码的执行流程、等待完成的工作,可以以更直观的方式发现代码的依赖关系。
The Timeline CPU Profiler view with Flow Events enabled and a sample selected.
3.1.5 Audio Profiler 模块
跟踪应用程序中花费在音频上的时间。
图标类别
如上图所示,这些时间被分为四个类别,如下表所示。
Playing Audio Sources 场景中在选定帧播放的音频源的总数。此信息可用于监测音频是否过载。
Audio Voices 选定帧中使用的音频(FMOD 通道)语音数。
Total Audio CPU 音频在选定帧中使用的 CPU 使用量。
Total Audio Memory 音频引擎在选定帧中使用的 RAM 量。
模块详细信息面板
选择 Audio Profiler 模块时,下面的详细信息面板将显示选定帧的音频数据的细分信息。两种视图可以用来检查 Audio Profiler 数据:Simple 和 Detailed。要更改显示视图,请使用详细信息面板中的左上角下拉选单(默认设置为 Simple)。
Simple视图
Total Audio Sources 场景中音频源的总数。
Playing Audio Sources 场景中播放的音频源的总数。
Paused Audio Sources 场景中暂停的音频源的总数。
Audio Clip Count 场景中音频剪辑的总数。
Audio Voices 项目使用的音频通道(FMOD 通道)的总数。
Total Audio CPU 音频使用的 CPU 总量。
DSP CPU 项目在加载类型为 Compressed In Memory 的非流式声音的混音、音频效果和解压缩中使用的 CPU 量。这不包括 Unity 在后台对加载类型为 Decompress On Load 并且选中 Load In Background 标志的声音进行解码所需的 CPU 量。
Streaming CPU 项目在应用程序中流式传输音频所使用的 CPU 量。
Other CPU 上文未涵盖的常规 CPU 开销。
Total Audio Memory 项目中音频使用的内存量。
Streaming File Memory 从磁盘渐进读取加载类型为 Streaming 的音频文件时,音频文件用于短期缓冲已压缩音频数据的内存量。
Streaming Decode Memory 加载类型为 Streaming 的音频文件用于缓冲已解码样本流的内存量。
Sample Sound Memory
加载类型为 Decompress On Load 的音频文件用于已解压缩样本数据的内存量。
注意:Unity 汇集了音频系统分配的内存,并且该内存在应用程序的运行时间内一直增长,直到达到饱和。音频系统会在内部重用分配的内存,在运行时无法压缩该内存。
Other Memory 音频系统中各种子系统造成的开销。
Detailed视图
Detailed 视图包含 Simple 视图中的所有信息,此外还包含对音频事件的详细每帧记录。可以按 Channels、Groups 或 Channels and Groups 类别查看这些信息。要打开此视图,请打开模块详细信息面板顶部的下拉选单,选择 Detailed,然后从面板顶部的工具栏中选择一个视图。Groups 视图显示混音器中总线的层级视图。Channels and Groups 视图将显示此信息以及有关所播放声音的信息。
Audio Profiler 的 Channel and Groups 视图
Detailed 视图中的信息分为以下几列:
Object 包含播放音频的音频源的游戏对象。
Asset 相应的游戏对象音频源正在播放的音频资源。
Volume 音频源应用于音频的音量。此音量组合了总体音量属性以及取决于距离的衰减曲线所应用的动态音量。
Audibility 音频播放的实际音量级别。这是音频源的音量与混音器通道应用的其他衰减量之和。
Plays Unity 播放音频的次数。该信息可用于调试 Unity 可能无法使用某些音频文件的逻辑错误。
3D 如果音频使用取决于距离的动态衰减和定向平移,则显示 YES。
Paused 如果音频在此帧中暂停,则显示 YES。
Muted 如果音频在此帧中已静音,则显示 YES。
Virtual 如果音频由于达到 Max Real Voice Count(可以在音频项目设置 (Audio Project Settings) 中设置此属性)而暂停,则显示 YES。Max Real Voice Count 可以设置 Unity 同时播放的音频源的最大数量。如果此处显示 true,则 Unity 会对该帧中具有更高可听度或优先级的其他音频设置更高优先级。
OneShot 如果 AudioSource.PlayOneShot() 播放了音频,则显示 YES。
Looped 如果 AudioSource.Play() 播放了音频,则显示 YES。
Distance 音频源到音频监听器 (AudioListener) 的距离。
MinDist 音频源曲线编辑器中定义的最小距离。此参数在音频周围定义一个球形区域;在该区域中,音量保持在恒定水平。
MaxDist 音频源曲线编辑器中定义的最大距离。此参数在音频周围定义一个球形区域;在该区域外,音量保持在恒定水平。
Time 音频播放中的当前相对时间。音频暂停播放时,此时间也会停止。
Duration 音频的长度(以秒为单位)。
3.1.6 Global Illumination Profiler 模块
Global Illumination Profiler 模块显示实时全局光照 (GI) 子系统的统计信息以及在所有工作线程中使用的 CPU 时间。
图表类别
Total CPU 在所有线程中所用的时间。
Light Probe 更新光照探针所用的时间。
设置 设置阶段所用的时间。
Environment 处理环境光照所用的时间。
Input Lighting 处理输入光照所用的时间。
Systems 更新系统所用的时间。
Solve Tasks 运行光能传递解算器任务所用的时间。
Dynamic Objects 更新动态游戏对象所用的时间。
Other Commands 更新其他命令所用的时间。
Block Command Write 处于被阻止状态下等待命令缓冲区的时间。
模块详细信息面板
选择 Global Illumination 模块时,下面的详细信息面板将显示应用程序在选定帧内花费的时间的细分信息。
Total CPU Time 所有线程中的总 Enlighten CPU 时间(以毫秒为单位)。
Probe Update Time 更新光照探针所用的时间(以毫秒为单位)。
Setup Time 设置阶段所用的时间(以毫秒为单位)。
Environment Time 处理环境光照所用的时间(以毫秒为单位)。
Input Lighting Time 处理输入光照所用的时间(以毫秒为单位)。
Systems Time 更新系统所用的时间(以毫秒为单位)。
Solve Tasks Time 运行光能传递解算器任务所用的时间(以毫秒为单位)。
Dynamic Objects Time 更新动态游戏对象所用的时间(以毫秒为单位)。
Time Between Updates 全局光照更新间隔时间(以毫秒为单位)。
Other Commands Time 处理其他命令所用的时间(以毫秒为单位)。
Blocked Command Write Time 处于被阻止状态下等待命令缓冲区的时间(以毫秒为单位)。
Blocked Buffer Writes 被阻止写入命令缓冲区的次数。
Total Light Probes 场景中的光照探针总数。
Solved Light Probes 自上次更新以来解算的光照探针数量。
Probe Sets 场景中的光照探针集数量。
Systems 场景中的 Enlighten 系统数量
Pending Material GPU Renders 排队等待在 GPU 上渲染的反照率/发光渲染数量。
Pending Material Updates 等待处理的材质更新数量。
3.1.7 GPU Usage Profiler 模块
GPU Usage Profiler 模块显示应用程序的 GPU 时间使用情况。
注意:
只能在运行模式 (Playmode) 下使用 GPU Profiler 或者用于应用程序的构建。不能用于对 Editor 进行性能分析。
如果在 Player Settings 中启用了 Graphics Jobs,则不支持 GPU 性能分析。
图表类别
Opaque 内置渲染管线渲染不透明对象的时间。
Transparent 内置渲染管线渲染透明对象的时间。
Shadows/Depth 内置渲染管线渲染阴影贴图的时间。
Deferred PrePass 内置延迟渲染管线渲染深度缓冲区预通道 (pre pass) 的时间。
Deferred Lighting 内置延迟渲染管线处理光照的时间。
PostProcess 内置渲染管线处理后期处理效果的时间。
Other 处理可编程渲染管线等其他事务的渲染时间。
模块详细信息面板
选择 GPU Usage 模块时,下面的详细信息面板将显示应用程序在选定帧内花费的时间的细分信息。详细信息面板有两个可用视图:
Hierarchy 按时间数据的内部层级结构对这些数据分组。此选项以降序列表格式显示应用程序调用的元素,默认按花费的时间排序。还可以按 GPU 时间总量或调用次数对这些信息进行排序。要更改用于对表进行排序的列,请单击该表列的标题。
Raw Hierarchy 以类似于发生计时的调用栈的层级结构显示时间数据。Unity 在此模式中单独列出每个调用栈,而不是像在 Hierarchy 视图中一样将它们合并。
选择 GPU Usage Profiler 模块后,此性能分析器的底部面板将显示选定帧的层级时间数据。从层级视图中选择一项即可在右侧面板中查看贡献的细分情况。
表视图所含列:
Total Unity 在特定函数上花费的总时间(以百分比表示)。
DrawCalls 此帧中调用此函数的次数。
GPU ms Unity 在特定函数上花费的总时间(以毫秒为单位)。
3.1.8 Memory Profiler 模块
有两种方法可以在 Unity 中分析应用程序的内存使用情况:
Memory Profiler 模块:这是内置性能分析器模块,可提供有关应用程序内存使用情况的基本信息。
Memory Profiler 包:这是可以添加到项目中的一个单独的包。这个包会向 Unity Editor 添加一个额外的 Memory Profiler 窗口,然后您可以使用该窗口来更详细地分析应用程序中的内存使用情况。可以存储和比较快照以便更轻松地查出内存泄漏,或者查看内存布局以查出内存碎片问题。
Memory Profiler 模块中会显示一些代表应用程序中分配的总内存的计数器。可以使用 Memory 模块来查看信息,例如已加载对象的数量以及每个类别占用的总内存。还可以查看每个性能分析器帧的 GC 分配数。
图表类别
Total Allocated 应用程序已使用的内存总量。
Texture Memory 应用程序中的纹理已使用的内存量。
Mesh Memory 应用程序中的网格已使用的内存量。
Material Count 应用程序中的材质实例数量。
Object Count 应用程序中的原生对象实例数量。
GC Used Memory GC 堆使用的内存量。
GC Allocated in Frame GC 堆中每帧分配的内存量。
模块详细信息面板
Simple和 Detailed视图
Simple视图
Simple 视图显示每个帧在 Unity 实时内存使用量的概况。
Unity 保留了可供分配的内存池,从而避免过于频繁向操作系统索取内存。性能分析器显示保留了多少内存,以及 Unity 使用了多少。
此信息也可通过 ProfilerRecorder API 及 Profiler Module Editor 获得,因此您可以将它们添加到自定义性能分析器模块中。
Total Used Memory Unity 使用和跟踪的总内存数量。
Total Reserved Memory Unity 用于跟踪目的和池分配的总保留内存。
GC Used Memory
GC Reserved Memory
托管代码使用的已用堆大小和总堆大小。此内存量是垃圾收集量。
Gfx Used Memory
Gfx Reserved Memory
驱动程序对纹理、渲染目标、着色器和网格数据使用的估计内存量。
Audio Used Memory
Audio Reserved Memory
音频系统的估计内存使用量。
Video Used Memory
Video Reserved Memory
视频系统的估计内存使用量
Profiler Used Memory
Profiler Reserved Memory
性能分析器功能使用并从系统中保留的内存。
System Used Memory
性能分析器中的值与操作系统任务管理器中显示的值不同,因为 Memory Profiler 不会跟踪系统中的所有内存使用情况。这包括某些驱动程序和插件使用的内存,以及用于可执行代码的内存。
在支持从操作系统获取应用程序总内存大小的平台上,System Memory Usage 大于 0 并且与任务管理器中的大小相同。
Texture Count
Texture Memory
已加载的纹理总数及其使用的内存。
Mesh Count
Mesh Memory
已加载的网格总数及其使用的内存。
Material Count
Material Memory
已加载的材质总数及其使用的内存。
AnimationClip Count
AnimationClip Memory
已加载的动画剪辑总数及其使用的内存。
Asset Count 已加载的资源总数。
GameObject Count 场景中游戏对象的总数
Scene Object Count 动态 UnityEngine.Object 的总数。此数值包括 GameObject Count,加上组件的总数,以及场景中所有非资源内容的数量。
Object Count 本机 UnityEngine.Object 总数是您的应用程序创建或加载的数量。此数值包括 Scene Object Count,加上所有资源的总数。如果此数值随时间推移而上升,表示应用程序创建了一些永不销毁或上载的游戏对象或其他资源。
GC Allocation In Frame Count
GC Allocated In Frame
托管分配的数量及其总大小(以字节为单位)。
Detailed 视图
Detailed 视图提供了应用程序当前状态的快照。
单击 Take Sample 按钮可捕获当前目标的详细内存使用情况。性能分析器获取此数据需要时间,因此 Detailed 视图不会提供实时详细信息。在性能分析器获取样本之后,Profiler 窗口会显示一个列表视图,您可以在其中更详细地浏览应用程序的内存使用情况。
Memory 模块 Detailed 视图
启用模块详细信息面板顶部的 Gather object references 设置可以收集有关生成快照时哪些项可能引用了对象的信息。性能分析器将此信息显示在窗口的右侧面板中。
列表视图将使用内存的对象将分为以下类别:
Other:资源、游戏对象或组件以外的对象。其中包括诸如 Unity 用于不同系统的内存之类的信息。
Not Saved:标记为 DontSave 的对象
Builtin Resources:Unity 编辑器资源或 Unity 默认资源,例如已添加到 Graphics 设置的 Always Included Shaders 列表中的着色器。
Assets:从用户或原生代码引用的资源。
Scene Memory:对象和附加的组件。
单击 Assets 或 Scene Memory 列表中的游戏对象时,该对象会在 Project 视图或 Scene 视图中突出显示。
注意:在 Other 类别中, System.ExecutableAndDlls 下报告的内存为只读内存。操作系统可能会根据需要丢弃这些页面,然后从文件系统重新加载这些页面。这样可以降低内存使用量,而且通常不会直接导致操作系统决定关闭应用程序(如果应用程序使用过多内存)。此外,其中一些页面也可能与使用相同框架的其他应用程序共享。
3.1.9 Physics Profiler 模块
Physics Profiler 模块显示物理引擎在场景中已处理的物理的相关信息。有助于诊断和解决与场景中的物理相关的性能问题或意外差异。
图标类别
分为七个类别,如下表所示。
Active Dynamic 活动状态的非运动刚体组件的数量。活动状态的刚体是指未处于睡眠状态的刚体。
Active Kinematic 活动状态的运动刚体组件的数量。在帧中调用 MovePosition 或 MoveRotation 时,运动刚体处于活动状态,并在下一帧中保持活动状态。注意:Unity 可能会在每帧多次处理已附加关节的运动刚体组件,这会计入显示的值中。
Static Colliders 未附加刚体组件或父游戏对象未附加刚体组件的游戏对象上的碰撞体组件数。具有刚体组件的游戏对象或父游戏对象不计为静态碰撞体,这些游戏对象称为复合碰撞体。复合碰撞体以方便的方式排列多个碰撞体,而不是将所有碰撞体放在与刚体组件相同的游戏对象上。
Rigidbody 物理引擎处理的刚体组件数量(与组件的睡眠状态无关)。
Trigger Overlaps 重叠触发器的数量(成对计数)。
Active Constraints 物理引擎已处理的原始约束的数量。约束用作关节的构建块以及碰撞响应。例如,限制 ConfigurableJoint 的线性或旋转自由度涉及每个限制的基本约束。
Contacts
场景中所有碰撞体之间的触点对总数,包括触发器重叠对的数量。一个接触点是一对触碰或重叠的碰撞体。
注意:一旦每个碰撞体对之间的距离低于特定的用户可配置限制,Unity 就会为该碰撞体对创建触点对。因此,可能会看到针对尚未触碰或重叠的刚体组件生成的触点。
模块详细信息面板
拥有的类别和图标类别的一致。
使用 Physics Profiler 了解性能问题
当一个复杂逻辑或图形帧需要很长时间时,此性能分析器必须每帧多次调用物理模拟。这意味着已经占用大量资源的帧会占用更多的时间和资源。这可能导致物理模拟会根据 Maximum Allowed Timestep 值而暂时停止;这个值可在 Project Settings 窗口(菜单:Edit > Project Settings > Time)中设置。
要在项目中检测到这一点,请选择 CPU Usage Profiler 模块 并在 Hierarchy 视图中的 Overview 部分中检查 Physics.Processing 或 Physics.Simulate 的调用次数。调用次数接近10表示有问题。
解决方案:降低物理模拟的频率。如果问题仍然存在,请检查在物理引擎必须使用大量模拟调用以便追赶游戏时间之前可能是什么原因导致了大型帧。有时,大型的图形帧可能会导致稍后在场景中进行更多物理模拟调用。
3.1.10 2D Physics Profiler 模块
2D Physics Profiler 模块显示物理引擎在场景中已处理的 2D 物理的相关信息。有助于诊断和解决与场景中的 2D 物理相关的性能问题或意外差异。
图表类别
分为九个类别,如下图所示:
Total Bodies 场景中 Rigidbody2D 的总数
Active Bodies 场景中活跃 Rigidbody2D 的总数。
Sleeping Bodies 场景中睡眠 Rigidbody2D 的总数。
Dynamic Bodies 场景中动态 Rigidbody2D 的总数。动态 Rigidbody2D 是最具交互性的 Rigidbody2D 类型。重力和作用力会影响此类型,这是最耗费资源的类型。
Kinematic Bodies 场景中运动 Rigidbody2D 的总数。运动 Rigidbody2D 被设计为在模拟条件下移动:重力和作用力不会影响此类型的 Rigidbody2D,您需要使用脚本来控制其行为方式。
Static Bodies 场景中静态 Rigidbody2D 的总数。静态物体不会在模拟条件下运动,这是耗费资源最少的 Rigidbody2D 类型。
Contacts 接触点的总数。一个接触点是一对触碰或重叠的碰撞体。为了解算重叠的接触点,物理引擎会施加脉冲,使接触点保持触碰而不会重叠。
Discrete Island Count 离散孤岛的总数。物理引擎将接触点分组成孤岛,然后进行解算。接触孤岛由连接在一起的接触点组成,但是接触点并非通过静态 Rigidbody2D 连接,实际上静态 Rigidbody2D 充当的是截断器。离散孤岛由使用离散碰撞检测模式的 Rigidbody2D 组成。如果使用多线程物理选项,过多接触孤岛对性能不利,因为物理引擎将每个孤岛作为一个作业来解算。
Continuous Island Count 连续孤岛的总数。这与 Discrete Island Count 相同,不同点在于它仅适用于使用连续碰撞检测模式的 Rigidbody2D。
模块详细信息面板
选择 2D Physics Profiler 模块时,下面的详细信息面板将显示应用程序在选定帧内用于 2D 物理的时间的细分信息。除了上表中列出的图表类别的详细细分信息之外,还有以下附加信息:
Discrete Bodies 使用离散碰撞检测模式的 Rigidbody2D 的数量。
Continuous Bodies 使用连续碰撞检测模式的 Rigidbody2D 的数量。
Joints 场景中 Joint2D 的数量。
Static Shapes
场景中静态形状的数量。形状是指 2D 物理引擎创建的原始形状。一个 Collider2D 可能生成单个或多个原始形状。要查看 Collider2D 的形状计数,可以查看 Inspector 或在脚本中使用 Collider2D.shapeCount。
静态形状是附加到静态 Rigidbody2D 的形状。静态形状通常用于非移动性物理几何体(例如平台)。
Active Shapes 场景中活跃形状的数量。活跃形状是附加到非睡眠 Rigidbody2D 的形状。静态形状始终不活跃,因为静态 Rigidbody2D 始终处于睡眠状态。
Sleeping Shapes 场景中睡眠形状的数量。睡眠形状是附加到睡眠 Rigidbody2D 的形状。这种状态的形状与活跃形状正好相反。
3.1.11 Rendering Profiler 模块
Rendering Profiler 显示有关 CPU 和 GPU 为渲染场景完成的工作的渲染统计信息和信息。可以使用这些统计信息来衡量场景不同区域的资源强度。
图表类别
Batches Count Unity 在一帧内处理的批次数。
SetPass Calls Count Unity 在一帧中切换用于渲染游戏对象的着色器通道的次数。一个着色器可能包含多个着色器通道,每个通道以不同的方式渲染场景中的游戏对象。
Triangles Count Unity 在一帧内处理的三角形数。
Vertices Count Unity 在一帧内处理的顶点数。
模块详细信息面板
在详细信息窗格的左上角,选择 Open Frame Debugger 以打开帧调试器,它为您提供有关渲染帧的各个绘制调用的信息。
单击 Rendering Profiler 模块时,窗口下半部分的详细信息窗格会显示详细的渲染统计信息。
SetPass Calls Count Unity 在一帧中切换用于渲染游戏对象的着色器通道的次数。一个着色器可能包含多个着色器通道,每个通道以不同的方式渲染场景中的游戏对象。
Draw Calls Count Unity 在一帧内发出的绘制调用总数。Unity 在将游戏对象渲染到屏幕时发出绘制调用。这个数字包括非批量绘制调用以及动态和静态批量绘制调用。
Total Batches Count Unity 在一帧内处理的批次总数。这个数字包括静态和动态批次。
Triangles Count Unity 在一帧内处理的三角形数。
Vertices Count Unity 在帧期间处理的顶点数。
(Dynamic Batching) 本部分包含有关动态批处理的统计数据。
Dynamic Batched Draw Calls Count Unity 合并为动态批次的绘制调用数。
Dynamic Batches Count Unity 在帧期间处理的动态批次数。
Dynamic Batched Triangles Count 动态批次中包含的游戏对象中的三角形数。
Dynamic Batched Vertices Count 动态批次中包含的游戏对象中的顶点数。
Dynamic Batching Time Unity 创建动态批处理结构所花费的时间。
(Static Batching) 本部分包含有关静态批处理的统计数据。
Static Batched Draw Calls Count Unity 合并为静态批次的绘制调用数。
Static Batches Count Unity 在一帧内处理的静态批次数。
Static Batched Triangles Count 静态批次中包含的游戏对象中的三角形数。
Static Batched Vertices Count 静态批次中包含的游戏对象中的顶点数。
(Instancing) 本部分包含有关 GPU 实例化的统计数据。
Instanced Batched Draw Calls Count Unity 合并为实例化批次的绘制调用数。
Instanced Batches Count Unity 在一帧内渲染实例化游戏对象的处理批次数。
Instanced Batched Triangles Count 实例化游戏对象中的三角形数。
Instanced Batched Vertices Count 实例化游戏对象中的顶点数。
Used Textures Count
Used Textures Bytes
Unity 在帧期间使用的纹理数以及纹理使用的内存量。
Render Textures Count
Render Textures Bytes
Unity 在帧期间使用的 RenderTextures 数以及 RenderTextures 使用的内存量。
Render Textures Changes Count Unity 在帧期间将一个或多个 RenderTextures 设置为渲染目标的次数。
Used Buffers Count
Used Buffers Bytes
所使用的 GPU 缓冲区和内存的总数。这包括顶点、索引和计算缓冲区以及渲染所需的所有内部缓冲区。
Vertex Buffer Upload In Frame Count
Vertex Buffer Upload In Frame Bytes
CPU 在帧中上传到 GPU 的几何体数量。这代表顶点/法线/ texcoord 数据。GPU 上可能已经有一些几何体。此统计信息仅包括 Unity 在帧中传输的几何体。
Index Buffer Upload In Frame Count
Index Buffer Upload In Frame Bytes
CPU 在帧中上传到 GPU 的几何体数量。这表示三角形索引数据。GPU 上可能已经有一些几何体。此统计信息仅包括 Unity 在帧中传输的几何体。
Shadow Casters Count 在一帧中投射阴影的游戏对象的数量。如果一个游戏对象投射多个阴影(因为多个光源照亮它),该对象投射的每个阴影都有一个条目。
注意:Rendering 模块的 Profiler 计数器也可在播放器中使用。
3.1.12 UI 和 UI Details Profiler
UI 和 UI Details Profiler 模块提供有关 Unity 在应用程序内布局和渲染用户界面方面花费的时间和资源的信息。使用此模块可以了解 Unity 如何为应用程序处理 UI 批处理,包括 Unity 为何以及如何对对象进行批处理。使用此模块还可以查明 UI 的哪一部分导致性能下降,或者在拖动时间轴的同时预览 UI。
图表类别
UI 和 UI Details Profiler 模块的图表被分为五个类别。
Layout Unity 在执行 UI 的布局通道方面花费的时间。这包括 HorizontalLayoutGroup、VerticalLayoutGroup 和 GridLayoutGroup 进行的计算。
Render UI 在完成渲染部分中花费的时间。这是直接渲染到图形设备的成本,或者是渲染到主渲染队列的成本。
Batches 显示一起批处理的绘制调用的总数。
Vertices 用于渲染 UI 某个部分的顶点总数。
Markers 显示事件标记。用户与 UI 交互(例如,单击按钮或更改滑动条值)时,Unity 将记录标记,然后将它们绘制为图表上的垂线和标签。
模块详细信息面板
选择 UI 或 UI Details Profiler 模块时,Profiler 窗口底部的模块详细信息面板会显示应用程序中 UI 的更多相关详细信息。
Object 应用程序在性能分析期间使用的 UI 画布的列表。双击一行可以突出显示场景中的匹配对象。
Self Batch Count Unity 为画布生成的批次数量。
Cumulative Batch Count Unity 为画布及其所有嵌套画布生成的批次数量。
Self Vertex Count 此画布渲染的顶点数量。
Cumulative Vertex Count 此画布和嵌套的画布渲染的顶点数量。
Batch Breaking Reason
Unity 拆分此批次的原因。有时 Unity 可能无法对对象同时进行批处理。
常见原因包括:
不与画布共面 (Not Coplanar With Canvas):批处理需要对象的矩形变换与画布共面(未旋转)。
画布注入索引 (CanvasInjectionIndex):CanvasGroup 组件存在并强制新建批次,例如在其余部分上显示一个组合框的下拉列表时。
不同的材质实例、矩形裁剪、纹理、A8 纹理用法 (Different Material Instance, Rect clipping, Texture, or A8TextureUsage):Unity 只能将具有相同材质、遮罩、纹理和纹理 Alpha 通道用法的对象一起进行处理。
GameObject Count 此批次中包含的游戏对象数量。
GameObjects 批次中的游戏对象的列表。
从列表中选择 UI 对象时,对象的预览将显示在面板右侧。预览上方的工具栏中有以下选项:
Detach:选择此按钮可在单独的窗口中打开 UI 画布。要重新连接该窗口,请将其关闭。
Preview background:使用下拉选单来更改预览背景的颜色。可以选择 Checkerboard、Black 或 White。如果 UI 具有特别浅色或深色的方案,这将很有用。
Preview type:使用下拉选单来选择 Standard、Overdraw 或 Composite Overdraw。
3.1.13 Video Profiler 模块
Video Profiler 模块显示有关应用程序中的视频所用资源的信息,例如内存、缓冲和视频剪辑的数量。借助这些信息可以确定应用程序在所选平台上播放和缓冲视频的效率。
图表类别
分为四个类别,如下表所示:
Total Video Sources 场景中视频源的总数。
Playing Video Sources 场景中正在播放的视频源数量。
Pre-buffered frames 预缓冲帧的总数。
Total Video Memory 应用程序中的视频所使用的系统内存量。
模块详细信息面板
在 Video Profiler 模块中选择帧后,Profiler 窗口底部的模块详细信息面板会显示有关场景中视频播放的更多详细信息。显示的信息如下:
Total Video Sources 场景中视频源的数量。
Playing Video Sources 场景中正在播放的视频源数量。
Paused Video Sources 暂停的视频源的数量。
Software Video Playback 平台本身不支持播放的视频的数量。
Pre-buffered frames 预缓冲帧的总数。
Pre-buffered frame limit 预缓冲帧限制。Unity 最多可为每个剪辑缓冲 16 帧。
Total frames dropped 为了保持实时性,Unity 必须跳过的帧数。应用程序运行缓慢且无法足够快地生成帧来实时播放时,就可能会发生这种跳帧的情况。
Video Clip Count 场景中视频剪辑的数量。
Total Video Memory 应用程序中的视频所使用的系统内存量。
3.1.14 Virtual Texturing Profiler 模块
Virtual Texturing Profiler 模块显示有关应用程序运行时屏幕上的纹理图块的信息,以及纹理使用的内存量。
注意:要使用 Virtual Texturing Profiler 模块,必须在您的项目的 Player Settings 中启用 Virtual Texturing (Edit > Project Settings > Player > Other Settings)。
图表类别
Required Tiles 在屏幕上可见的纹理图块的数量。这些是着色器尝试采样以渲染当前帧的图块。
Max Cache Mip Bias 自动 Mipmap 偏差应用于具有相同纹理格式的所有纹理。如果此值不为零,则缓存无法容纳该格式的所有可见图块。Mip 偏差越高,纹理质量越低。
Max Cache Demand 所有缓存此帧的 GPU 的最高缓存需求。
Missing Streaming Tiles 当前在屏幕上可见但尚未加载到视频内存中的图块数量。应用程序会尽快从磁盘流式传输或从主内存复制这些图块。
Missing Disk Data 应用程序需要从磁盘读取以满足当前帧的剩余数据(以字节为单位)。
模块详细信息面板
单击 Virtual Texturing Profiler 模块时,窗口下半部分的详细信息窗格会进一步显示详细的统计信息。
Required Tiles
在屏幕上可见的纹理图块的数量。这些是着色器尝试采样以渲染当前帧的图块。如果所有这些图块都加载到 GPU 缓存中,则 Unity 会根据当前缓存大小以最高纹理质量渲染帧。
除非场景被冻结,否则尚有一些图块未加载到 GPU 内存中。在这种情况下,虚拟纹理样本使用来自内存中较高 Mipmap 的较低质量样本,直到更高质量的样本到达内存。
缓存 Mipmap 偏差会影响所需图块的数量。如果所有缓存的 Mipmap 偏差不为零,则 Required Tiles(所需图块)的数量低于最佳纹理质量所需的数量。
Atlases 虚拟纹理空间或图集的数量(最多 64 个)。Unity 将通过虚拟纹理流式传输的纹理作为图集发送到大型虚拟纹理空间中。此过程是自动和透明的。
Max Cache Mip Bias 具有最高 Mip 偏差的 GPU 缓存的 Mip 偏差。如果不为零,则至少一个缓存不够大,无法容纳所有纹理图块以最佳纹理质量渲染当前帧。
Max Cache Demand
所有缓存此帧的 GPU 的最高缓存需求,表示为 GPU 的百分比。具有最高需求的 GPU 缓存可能需要更大,以避免此缓存的 Mipmap 偏差。
如果 Max Cache Demand 统计数据百分比较低,则该缓存对于当前渲染分辨率和内容可能太大。这样做的主要缺点是您的应用程序使用的 GPU 内存超出其需求,但如果您的应用程序不受内存限制,这不是问题。
Total CPU Cache Size Unity 从磁盘加载纹理图块后分配给存储的纹理图块的内存量。
Total GPU Cache Size Virtual Texturing 模块在选定帧中分配的所有 GPU 缓存的大小。Unity 仅在渲染使用该纹理格式的纹理的材质时创建 GPU 缓存。
Missing Disk Data
(Player builds only) 应用程序需要从磁盘读取以满足当前帧的剩余数据(以字节为单位)。队列中可能有更多的磁盘读取请求是来自不再可见的前一帧中的请求。因此,这是在没有新图块可见的情况下从磁盘读取的最小数据量。应用程序读取的实际数据量可能更大。
Missing Streaming Tiles
(Player builds only) 当前在屏幕上可见但尚未加载到内存中的图块数量。这些图块会尽快从磁盘流式传输。例如,如果摄像机移动,这个数字可能会更高。如果场景和摄像机冻结并且看不到新的图块,它应该很快降到零。
Read From Disk
(Player builds only) Unity 完成此帧的磁盘读取操作的字节数。
% Cache demands
(Player builds only) 每个图形格式使用的缓存需求量。注意:此统计信息在自定义性能分析器中不可用
Mipmap bias per format
(Player builds only) 每个图形格式使用的 Mipmap 偏差缓存量。注意:此统计信息在自定义性能分析器中不可用
3.1.15 Profiler Module Editor(性能分析器模块编辑器)
Profiler Module Editor 工具可用于将您自己的自定义模块添加到 Unity Profiler 窗口。还可以向模块添加内置计数器,或使用运行时 API 将您自己的自定义计数器添加到模块。
适用于需要深入了解要进一步分析的统计信息,或打算将有关您的应用程序的自定义统计信息添加到 Profiler 窗口时。
打开 Profiler 窗口 (Window > Analysis > Profiler),然后选择 Profiler Modules 下拉选单。
选择齿轮图标,打开Profiler Module Editor
该窗口包含三列:
Profiler Module 的列表: 此列表包含可添加到 Profiler 窗口的所有可用模块。内置模块在列表中呈灰色显示,表示您无法编辑其内容。您可以拖放模块以重新排列它们在 Profiler 窗口中的显示顺序。当您创建自己的自定义性能分析器模块时,该模块也会出现在此列表中。
Profiler Module 信息窗格(仅在您创建或选择自定义模块时出现):列出自定义模块中包含的计数器
可用计数器(仅在您创建或选择自定义模块时出现):列出您可以添加到自定义模块的可用计数器。
创建自定义模块
要创建自定义模块,请选择 Profiler Module Editor 窗口左下角的 Add 按钮。Unity 在名为 New Profiler Module 的列表中添加了一个新的 Profiler 模块。要重命名该模块,请单击文本字段并使用键盘设置名称。
向模块添加计数器
要在自定义性能分析器模块中收集数据,必须至少添加一个计数器以便模块进行跟踪。可用计数器列表在 Available Counters 窗格中显示。
要将计数器添加到模块,请在 Available Counters 列表中选择该计数器,然后选择 Add Selected 按钮。或者,您可以双击计数器将其添加到模块中。Unity 然后将这些计数器添加到选定的 Profiler 模块。要一次向模块添加多个计数器,您可以按住 Shift 键并单击两个计数器以选择两者之间的所有计数器,或者您可以按住 Ctrl逐一选择计数器,然后选择 Add Selected 按钮。
使用自定义模块
选择 Profiler Module Editor 窗口右下角的 Save Changes 按钮。Unity 关闭窗口,然后您可以在 Profiler 窗口中看到您的新模块。
4、数据分析
1、一般的,通过查看CPU分析器开始调查。CPU分析器提供了应用程序中CPU执行时间最长的部分的概览。
2、利用CPU分析器提供的信息来确定应该查看哪些其他分析器。例如,如果我们确定物理函数需要很长时间才能运行,我们将使用Physical profiler收集有关应用程序中物理性能的更详细信息。
4.1 常见性能问题
渲染
垃圾回收
物理计算
脚本
4.3 确定造成性能问题的原因
首先通过CPU分析器分析垂直同步、渲染、垃圾回收、物理、脚本等是否是造成性能问题的原因。定位到造成性能问题的主要因素,如渲染,然后再切换到渲染性能分析器模块分析具体内容。
4.3.1 排除垂直同步的影响
我们可以在 CPU 分析器中选择要隐藏的信息。这可以让我们忽略对当前研究没有帮助的信息。
隐藏垂直同步的步骤如下:
1、点击 CPU分 析器
2、在 Profiler窗口的顶部, CPU 分析器区域显示当前关注的数据,点击标记为 VSync 的黄色正方形就可以隐藏垂直同步的信息
4.3.2 在层级结构视图中无视垂直同步信息
没有办法在层级结构视图中隐藏垂直同步信息,但我们知道了它长什么样子,我们就可以无视它。
无论什么时候,我们在层级结构视图中看到WaitForTargetFPS,这意味着我们的游戏在等待垂直同步,我们不需要研究这个函数,忽略它就好。
4.3.3 屏蔽垂直同步
垂直同步不能在所有的平台上都屏蔽:许多(如 IOS )强制使用垂直同步。但如果我们正在为一个不需要强制使用垂直同步的平台开发,我们就可以屏蔽掉垂直同步。点击 Edit -> Project Settings -> Quality ,找到 VSync Count ,下来菜单选中 Don’t Sync(默认的)。
4.3.4 渲染(Rendering)
尝试修复渲染问题之前,需要先确定应用程序是 CPU 限制还是 GPU 限制,因为它们的解决方式不一样。简单的说, CPU 负责决定绘制什么,而 GPU 负责绘制。如果渲染问题归咎于 CPU 耗时太多,那游戏就属于 CPU 限制(GPU bound),如果渲染问题归咎于 GPU 耗时太多,那应用程序就属于 GPU 密限制(GPU bound)。
辨别应用程序是否是 GPU 限制(GPU bound)
1、点击 GPU 分析器
2、查看屏幕正中心区域,那里显示了当前选中帧的 CPU 和 GPU 耗时。
如果 GPU 耗时大于 CPU 耗时,则我们可以确认我们的游戏是 GPU 限制(GPU bound)。
如果 GPU 分析器不能在目标设备上使用,可以通过观察 CPU 分析器。如果我们看到 CPU 正在等待 GPU 完成任务,这就是意味着应用程序是 GPU 限制。为了查明是否存在这种情况,我们可以执行以下步骤:
点击选择 CPU 分析器。
检查 Profiler 窗口底部区域显示的当前帧信息和分析器信息。
在区域左上角的下拉菜单中选择层级结构视图。
选择 Time ms 列头,函数耗时按时间排序。
如果函数 Gfx.WaitForPresent 是 CPU 分析器中最耗时的函数,这表明 CPU 正在等待 GPU 。这意味着我们的应用程序是 GPU 限制(GPU Bound)。
辨别应用程序是否是CPU限制
如果还没有确认造成性能问题的原因,可以研究基于 CPU 的渲染问题。
点击选择 CPU 分析器。
Profiler窗口顶部信息会显示分析数据,检测图像中代表渲染的部分。可以通过点击关键字旁边的带颜色的正方形图片显示或隐藏这些数据。
如果慢帧的大部分时间被渲染占用了,这意味着渲染可能是造成我们问题的原因。我们可以按以下步骤继续挖掘来确认:
点击选择 CPU 分析器。
检测 Profiler 窗口显示的当前帧信息和分析器信息。
在分析数据区域左上角下拉菜单中选择层级结构。
选择列头 Time ms ,按函数耗时排序。
点击选择最顶部的函数。
如果选中的是一个渲染函数,CPU 分析器图像将会高亮显示 Rendering 图像,这也意味着渲染相关的操作是造成性能问题的原因,也可以确认应用程序是 CPU 限制。留意函数名和是哪个线程执行这个函数。
4.3.5 垃圾回收(GarbageCollector)
垃圾回收是 Unity 自动内存管理的特性。
1.点击选择 CPU 分析器。
2.在 Profiler 窗口,黄色部分代表垃圾回收,可以点击名字旁边的小色块显示或取消垃圾回收的数据采集。在下面的截图中,拖拽 GarbageCollector 到顶部,并且点击关掉了其他方面的数据。
垃圾回收过度:慢帧的大部分时间被垃圾回收占用。
继续分析:
点击选择CPU分析器,检测Profiler窗口底部显示的当前帧相应信息。
底部区域左上角下拉按钮选择层次结构视图。
选择 Time ms 列头,以函数耗时排序。
如果 GC.Collect() 函数出现,并且耗时比较多,就可以确认我们的应用程序有垃圾回收问题。
4.3.5 物理(Physics)
点击选择 CPU 分析器。
在 Profiler 窗口显示数据的顶部,检测代表 Physics 的图像(橙色图像)。
如果慢帧的大部分时间被物理占用,那么可以确认物理计算是造成我们问题的原因。我们可以进一步研究以确认问题:
点击选中 CPU 分析器,检测 Profiler 下方区域显示的当前帧详细信息。
在底部区域左上角的下拉菜单选择层级结构视图。
选择 Time ms 列头,按函数耗时排序。
点击选择顶部的函数。
如果选中的是一个物理函数,CPU 分析器图像将会高亮显示 Physics 图像。如果是这种情况,可以确定造成性能问题的原因和物理计算相关。
4.3.6 脚本
现在我们检测缓慢的或过度复杂的脚本是否是造成性能问题的原因。脚本,这里将的是非 Unity 引擎代码。这些脚本通常是我们自己写的,或者是第三方插件引入的。
分析步骤:
点击选择 CPU 分析器
在 Profiler 窗口显示数据的顶部,检测代表Script的图像,我们可以通过点击关键字旁边的颜色方块显示或隐藏图像数据。
如果慢帧大部分时间被scripts占用,那可以确认开发者写的脚本是造成问题的原因。我们可以继续研究确认问题:
点击选中CPU分析器,检测Profiler窗口下方的当前帧详细数据。
在底部区域左上角的下拉菜单选择层级结构视图。
选择 Time ms 列头,按函数耗时排序。
点击选择顶部的函数。
如果是自己写的脚本,CPU 分析器图像将会高亮显示 Scripts 图像。这种情况下,我们可以确认造成性能问题的原因与我们写的脚本有关。
注意:当我们游戏包含渲染相关的函数,如 Image Effects 脚本或 OnWillRenderObject 或 OnPreCull 函数,这些将会出现在渲染分析器而不是脚本分析器。