Unity教程||Unity移动端游戏性能优化

Posted 爱编程的鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity教程||Unity移动端游戏性能优化相关的知识,希望对你有一定的参考价值。

物理

Unity 的内置物理系统 (Nvidia PhysX) 在移动设备上开销较大。下面的提示可以帮助您每秒减少更多帧。

优化设置

在 PlayerSettings 中,尽可能选中 Prebake Collision Meshes。

启用 Prebake Collision Meshes

请务必同时编辑 Physics 设置 (Project Settings > Physics)。尽可能简化 Layer Collision Matrix。

禁用 Auto Sync Transforms 并启用 Reuse Collision Callbacks。

修改物理项目设置以进一步提高性能

留意 Profiler 的 Physics 模块是否有性能问题

简化碰撞体

网格碰撞体开销较大。用简单的原始碰撞体或网格碰撞体代替更复杂的网格碰撞体来近似原始形状。

使用原始或简化网格来表示碰撞体

使用物理方法移动刚体

使用类方法(如 MovePosition 或 AddForce)来移动 Rigidbody 对象。直接转换其 Transform 组件可能导致重新计算物理世界,在复杂场景中,这样需要较大开销。

在 FixedUpdate 中而不是 Update 中移动物理体。

修改固定时间间隔

Project Settings 中的默认 Fixed Timestep 是 0.02 (50 Hz)。根据目标帧率对此进行更改(例如,对 30 fps 设置为 0.03)。

否则,如果帧率在运行时下降,也就是说 Unity 每帧都多次调用 FixedUpdate,可能会因物理内容过多而造成 CPU 性能问题。

Maximum Allowed Timestep 对帧率下降时物理计算和 FixedUpdate 事件可以使用的时间进行限制。降低该值意味着在性能顿挫过程中,物理系统和动画会缓慢下来,但也会减小其对帧率的影响。

将以减 Fixed Timestep 修改为与目标帧率相符,降低 Maximum Allowed Timestep 以减少性能毛刺

通过 Physics Debugger 实现可视化

使用 Physics Debug 窗口 (Window > Analysis > Physics Debugger) 可帮助故障检查有问题的碰撞体或者出现差异的情况。下面是一个颜色编码的指示器,指示哪些游戏对象可以相互碰撞。

Physics Debugger 可帮助您可视化物理对象能够相互交互的方式

有关更多信息,请参阅 Unity 文档中的物理调试可视化。https://docs.unity3d.com/cn/current/Manual/PhysicsDebugVisualization.html

用户界面 UI

Unity UI (UGUI) 常常是性能问题的来源。Canvas 组件生成和更新 UI 组件的网格并向 GPU 发出绘制调用。它的运行开销很大,因此,在使用 UGUI 时,请注意以下因素。

Unity UI 文档:https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/index.html

划分画布

如果是包含成千上万个元素的大型画布,更新单个 UI 元素就必须更新整个画布,这可能会造成 CPU 尖峰。

利用 UGUI 的功能可以支持多个画布。根据 UI 元素的更新频率要求,划分这些元素。将静态 UI 元素保留在单独的画布上,将同时更新的动态元素保留在较小的子画布上。

确保每个画布中的 UI 元素都有相同的 Z 值、材质和纹理。

隐藏不可见的 UI 元素

可能有些 UI 元素(如仅当角色收到伤害时才出现的生命值血条)只偶尔在游戏中出现。如果不可见的 UI 元素是活动的,它仍然可能使用绘制调用。显式禁用所有不可见的 UI 组件,在需要时再重新启用。

如果只需要关闭画布的可见性,请禁用 Canvas 组件而不是游戏对象。这样就不必重新构建网格和顶点。

限制 GraphicRaycaster 和禁用 Raycast Target

输入事件(如屏上触摸或单击)需要 GraphicRaycaster 组件。它只是循环处理屏幕上的每个输入点,检查它是否在 UI 的 RectTransform 之内。

从层级视图的顶层画布中移除默认的 GraphicRaycaster。只向需要交互的各元素(按钮、滚动矩形等)添加 GraphicRaycaster。

禁用在默认情况下处于活动状态的 Ignore Reversed Graphics

另外,在所有不需要 Raycast Target 的 UI 文本和图像上将其禁用。如果是包含很多元素的复杂 UI,所有这些小更改都可以减少不必要的计算。

尽可能禁用 Raycast Target

避免使用布局组

布局组的更新很低效,应少量使用。如果内容是动态的,应完全避免不用,而是使用锚点进行比例布局。或者,创建自定义代码,在 Layout Group 组件设置 UI 之后,将该组件禁用。

Layout Group 文档:https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/UIAutoLayout.html

如果动态元素确实需要使用布局组(水平、垂直、网格),应避免嵌套它们,从而改善性能。

布局组会降低性能,尤其是在嵌套时

避免使用大型列表和网格视图

大型列表和网格视图开销很大。如果需要创建大型列表或网格视图(如包含成百上千项目的物品栏屏幕),可以考虑重复使用较小的 UI 元素池,而不是为每个项目都创建 UI 元素。请参阅此示例 GitHub 项目了解实际方法。

GitHub 项目:

https://github.com/boonyifei/ScrollList

避免大量使用重叠元素

对大量 UI 元素(如卡牌游戏中堆叠的卡牌)分层会造成过度绘制。自定义代码在运行时将分层元素合并到更少的元素和批次中。

使用多种分辨率和宽高比

现在,移动设备使用的分辨率和屏幕大小极为不同,创建不同的 UI 版本可以按设备提供最佳体验。

UI 版本:https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/HOWTO-UIMultiResolution.html

使用设备模拟器可以预览 UI 在各种受支持的设备上的呈现。您也可以在XCode 和 android Studio 中创建虚拟设备。

设备模拟器:https://docs.unity3d.com/Manual/com.unity.device-simulator.html

使用设备模拟器预览各种屏幕格式

使用全屏 UI 时,隐藏其他全部内容

如果暂停屏幕或者启动屏幕遮住场景中的其他全部内容,则禁用摄像机对 3D 场景的渲染。同样,禁用隐藏在顶层画布之后的所有背景画布元素。

由于不需要以 60 fps 的帧率进行更新,可以考虑在全屏 UI 过程中降低 Application.targetFrameRate。

将摄像机分配给世界空间画布和摄像机空间画布

将 Event 或 Render Camera 字段留空会使 Unity 填充 Camera.main,这会导致不必要的开销。

尽可能使画布 RenderMode 采用 Screen Space - Overlay,这样就不需要摄像机。

使用世界空间 (World Space) 渲染模式时,请务必填充 Event Camera

音频

尽管音频通常不会造成性能瓶颈,还是可以进行优化以节省内存。

尽量使用单声道声音剪辑

如果要使用 3D 空间音频, 请以单声道 (single channel) 的形式创作声音剪辑,或者启用 Force To Mono 设置。在运行时定位使用的多声道声音会扁平化为单声道源,因此会增加 CPU 开销和浪费内存。

尽可能使用原始未压缩 WAV 文件作为源资源

如果使用任何压缩格式(如 MP3 或 Vorbis),Unity 会将其解压并在构建时重新压缩。这样会导致两个有损通道,从而降低最终质量。

压缩剪辑并降低压缩比特率

通过压缩减小剪辑的大小和内存使用量 :

对大多数声音使用 Vorbis(或者对不循环的声音使用 MP3)。

对常用的短声音使用 ADPCM(如脚步声、枪声)。相比于未压缩的 PCM,这样可以减小文件大小,在播放时又可以很快解码。

移动设备上的音效最高为 22,050 Hz。使用较低设置通常对最终质量影响很小,当然,请使用您自己的耳朵来判断。

优化 AudioClip 的导入设置

选择正确的加载类型

每个剪辑大小的设置都不同。

小剪辑 (< 200 kb) 应采用 Decompress on Load。将声音解压缩为原始 16 位 PCM 音频数据,会导致 CPU 开销和内存占用,因此,这仅适用于短声音。

中等剪辑 (>= 200 kb) 应保持为 Compressed in Memory。

大文件(背景音乐)应设置为 Streaming。否则,整个资源会一次性加载到内存中。

从内存中卸载静音的音频源 (Audiosources)

实现静音按钮时,不要只是将音量设置为 0。可以销毁 AudioSource 组件,从而将其从内存中卸载,这样,播放器不需要过于频繁地切换开关。

Unity3D 官方移动游戏优化指南6.项目配置


有一些项目设置会影响移动端性能。

降低或禁用Accelerometer Frequency

Unity 每秒对移动端的加速度计进行几次池操作。如果在应用程序中不会使用,请将其禁用,或者降低其频率,从而提升性能。

【Unity3D

如果在移动游戏中不会使用 Accelerometer Frequency,请务必将其禁用。

禁用不必要的 Player 或Quality 设置

在 Player 设置中,对不支持的平台禁用 Auto Graphics API,以便防止生成过多着色器变体。如果应用程序不支持,对较旧的 CPU 禁用 Target Architectures。

在 Quality 设置中,禁用不需要的质量级别。

禁用不必要的物理设置

如果游戏不使用物理设置,请取消选中 Auto Simulation 和 Auto Sync Transforms。否则它们会降低应用程序运行速度,却并无任何可见的好处。

选择正确的帧率

移动端项目必须在帧率和电池续航时间以及热节流之间获得平衡。不需要将设备限值推向 60 fps,可以折衷以 30 fps 运行。Unity 默认移动端为 30 fps。

您也可以通过 Application.targetFrameRate 在运行时动态调整帧率。例如,您甚至可以将缓慢或相对静止的场景降至 30 fps 以下,而将玩游戏时的 fps 设置保留为较高值。

避免使用过多层级

拆分层级!在层级视图中如果游戏对象不需要嵌套,请简化父子化。较少的层级关系将受益于多线程刷新场景中的变换 (Transform)。复杂层级关系会发生不必要的变换 (Transform) 计算以及更多垃圾收集开销。

请参阅​​优化层级关系​​​和此 ​​Unite 报告​​了解变换 (Transform) 的最佳实践。

变换一次,而非两次

另外,移动变换 (Transform) 时,使用​​Transform.SetPositionAndRotation​​ 可以一次就同时更新位置和旋转。这样可以避免两次修改变换(Transform)的开销。

如果需要在运行时​​初始化​​游戏对象,一项简单的优化是在初始化过程中父子化和重新定位 :

GameObject.Instantiate(prefab, parent); 
GameObject.Instantiate(prefab, parent, position, rotation);

有关 Object.Instantiate 的更多详细信息,请参阅​​脚本 API​​。

假设Vsync 已启用

移动平台不渲染半帧。即使在编辑器中禁用 Vsync (Project Settings > Quality), Vsync 在硬件级别也处于启用状态。如果 GPU 无法足够快地刷新,将保持当前帧,从而有效降低每秒帧数。

以上是关于Unity教程||Unity移动端游戏性能优化的主要内容,如果未能解决你的问题,请参考以下文章

[Unity优化] Unity CPU性能优化 (难度3 推荐4)

Unity游戏项目性能优化总结 (难度3 推荐4)

Unity3D 官方移动游戏优化指南6.项目配置

Unity3D 官方移动游戏优化指南6.项目配置

Unity3D 官方移动游戏优化指南6.项目配置

Unity3D 官方移动游戏优化指南2.性能分析