这是系列文章中的第一篇,详细介绍了 Unity 项目的优化技巧。使用它们作为以更少资源以更高帧速率运行的指南。尝试这些最佳实践后,请务必查看该系列的其他页面:
资产管道 可以极大地影响您的团队的生产力和游戏的性能。通过与经验丰富的技术艺术家合作,您的团队将有能力定义和执行资产格式和规范,以确保流程顺利进行。
不要依赖默认设置。使用特定于平台的 “Override” 选项卡来优化纹理和网格几何等资产。不正确的设置可能会导致构建尺寸更大、构建时间更长以及 GPU 性能和内存使用率较差。考虑使用 预设 功能进一步 自定义项目的基线设置 。
请参阅 本指南 ,了解处理艺术资产的最佳实践。有关移动设备专用指南,请查看有关 移动应用程序 3D 艺术优化的Unity Learn课程。
在 播放器设置中,禁用 自动图形 API ,并删除您不计划在每个目标平台上支持的其他图形 API。这可以防止产生过多的着色器变体。如果您的应用程序不支持旧 CPU,请禁用 目标架构 设置。
了解有关 图形 API 的更多信息。
将脚本后端从 Mono 切换到 IL2CPP(中间语言到 C++)可以提供更好的整体运行时性能。但是,它也会增加构建时间。一些开发人员更喜欢在本地使用 Mono 以实现更快的迭代,然后切换到 IL2CPP 来构建机器和/或发布候选版本。有关减少构建时间的更多信息,请参阅 优化 IL2CPP 构建时间文档 。
注意:通过使用此选项,Unity 会将脚本和程序集中的 ILcode 转换为 C++,然后为目标平台创建本机二进制文件 (.exe、.apk、.xap)。
请参阅 IL2CPP 内部简介 或查阅 编译器选项手册页 ,了解各种编译器选项如何影响运行时性能。
移动项目必须平衡帧速率与电池寿命和热节流。想想每秒的帧数(fps)。
不要以 60 fps 的速度突破设备的限制,而应考虑以 30 fps 的速度运行作为折衷方案。请注意,Unity 已将移动设备的默认帧率为 30 fps。
您还可以使用 Application.targetFrameRate在运行时动态调整帧速率。例如,您可以将速度降至 30 fps 以下以适应缓慢或相对静态的场景(例如菜单),并保留更高的 fps 设置以进行游戏。
移动平台不会渲染半帧。即使您在编辑器中禁用 Vsync(项目设置 > 质量),它仍然在硬件级别启用。如果 GPU 无法足够快地刷新,当前帧将被保留,从而降低 fps。
更多信息请参阅 文档。
Unity 每秒会轮询您移动设备的加速度计数次。如果您的应用程序中未使用它,请禁用它,或降低其频率以获得更好的性能。
了解有关 加速度计的更多信息。
分割你的层次结构。如果您的 游戏对象 (GameObjects) 不需要嵌套在 层次结构 (Hierarchy)中,请简化父级关系。
较小的层次结构可以通过多线程来刷新场景中的 变换 。复杂的层次结构会导致不必要的转换计算和 垃圾收集 (GC) 成本。
请参阅 优化层次结构 和 此 Unite 演讲 以获取有关变换的提示。
上面的两个示例使用相同的模型和纹理 - 但顶部的设置比底部的设置消耗的内存多五倍以上,而视觉质量并没有好多少。
如果正确使用,纹理压缩 可以提供显著的性能优势,例如更快的加载时间、更小的内存占用以及显著提高的渲染性能。压缩纹理仅使用未压缩的 32 位 RGBA 纹理所需内存带宽的一小部分。
请参阅针对目标平台的 纹理压缩格式推荐列表 。
纹理可能会使用过多的资源,因此优化导入设置至关重要。一般而言,请尝试遵循以下准则:
- 降低最大尺寸:使用产生视觉上可接受结果的最小设置。这是非破坏性的并且可以快速减少您的纹理内存。
- 使用二的幂(POT):Unity 要求纹理压缩格式采用 POT 纹理尺寸。
- 关闭“读/写启用”选项:启用后,此选项会在 CPU 和 GPU 可寻址内存中创建副本,使纹理的内存占用量加倍。在大多数情况下禁用它,并且仅在运行时生成需要覆盖的纹理时启用它。您还可以通过 Texture2D.Apply强制执行此选项,并将 makeNoLongerReadable 设置为 True。
- 禁用不必要的 Mip Maps:对于在屏幕上保持一致大小的纹理(例如 2D Sprites 和 UI Graphics),不需要 Mip Maps。但是,对于与相机距离有变化的 3D 模型,请保持 Mip Maps 处于启用状态。
了解有关 纹理导入设置的更多信息。
图集化是将几个较小的纹理组合成一个较大的纹理的过程。纹理图集 减少了内存使用量并需要更少的绘制调用,从而减少了 GPU 所需的工作量。
- 对于 2D 项目:使用 Sprite Atlas(Asset > Create > 2D > Sprite Atlas)而不是渲染单个精灵或纹理。
- 对于 3D 项目:您可以使用您选择的 数字内容创作 (DCC) 包。还可以使用一些第三方工具(例如 MA_TextureAtlasser 或 TexturePacker) 来构建纹理图集。
结合纹理并重新映射 UV,适用于任何不需要高分辨率地图的 3D 几何体。可视化编辑器使您能够设置纹理图集或 精灵表中的尺寸和位置,并确定其优先级。
纹理打包器 将各个贴图合并为一个大纹理。然后,Unity 可以发出单个绘制调用来以较小的性能开销访问打包的纹理。
在这里阅读有关 Sprite Atlases 的更多信息。
高分辨率模型需要使用更多的内存,并且可能需要 GPU 做更多的工作。因此,应尽量将场景中游戏对象的几何复杂性保持在最低限度。否则,Unity 必须将重要的顶点数据推送到显卡。
最佳做法是减少 DCC 软件中的模型并从相机的视角删除看不见的多边形。例如,如果您从未看到过橱柜背面靠在墙上,则模型那里就不应该有任何面。
请注意,在现代 GPU 上,瓶颈通常与多边形密度有关,而不是多边形数量。尝试对所有资产进行艺术传递,以减少远处物体的多边形数量。微三角形 可能是导致 GPU 性能不佳的一个重要原因。
根据目标平台,考虑通过高分辨率纹理添加细节来补偿低多边形几何。使用纹理和法线贴图而不是增加网格的密度。通过将尽可能多的细节烘焙到纹理中来降低像素复杂性。例如,您可以捕获纹理本身中的镜面高光,以避免在片段着色器中计算高光。
保持警惕并记得定期进行分析。毕竟,这些技术会影响性能,并且可能不适合您的目标平台。
与纹理非常相似,如果不小心导入,网格可能会消耗过多的内存。尝试以下技巧来最大限度地减少网格的内存消耗:
- 网格压缩:网格压缩可以减少磁盘空间(尽管运行时内存不受影响)。同时,网格量化可能会导致不准确性,因此请尝试不同的压缩级别来了解哪种级别适合您的模型。
- 禁用读/写:启用此选项将在内存中复制网格,将网格的一个副本保留在系统内存中,将另一个副本保留在 GPU 内存中。大多数情况下,您应该禁用它。在 Unity 2019.2 及更早版本中,默认选中此选项。
- 禁用装备和混合形状:如果您的网格不需要骨骼或混合形状动画,请禁用这些选项。
- 禁用法线和切线:如果您绝对确定网格的材质不需要法线或切线,请取消选中这些选项以获得额外的节省。
播放器设置中提供了其他网格优化选项:
- 顶点压缩 设置每个通道的顶点压缩。例如,您可以对除位置和光照贴图 UV 之外的所有内容启用压缩。这可以减少网格的运行时内存使用量。
- 注意:每个网格的导入设置中的网格压缩设置会覆盖顶点压缩设置。在这种情况下,网格的运行时副本未压缩,可能会使用更多内存。
- 优化网格数据 会从网格中删除应用到其上的材质不需要的任何数据(例如切线、法线、颜色和 UV)。
通过自动化审计过程,您可以避免意外更改资产设置。AssetPostProcessor 可以帮助您标准化导入设置或分析现有资产。它允许您在导入资产时运行脚本,并且本质上提示您在导入模型、纹理、音频等之前和/或之后自定义设置。
Unity 使用环形缓冲区将纹理推送到 GPU。您可以通过 QualitySettings.asyncUploadBufferSize手动调整此异步纹理缓冲区。
如果上传速度太慢或者主线程在同时加载多个纹理时停顿,请调整 这些纹理缓冲区。您通常可以将该值(以 MB 为单位)设置为您需要在场景中加载的最大纹理的大小。
请记住,更改默认值可能会导致高内存压力。此外,Unity 分配环形缓冲区内存后,您无法将其返回给系统。如果 GPU 内存过载,GPU 会卸载最近且最少使用的纹理,并在下次进入相机视锥时强制 CPU 重新上传它。
Mip Map Streaming 系统让您可以控制哪些 Mip Map 级别应加载到内存中。通过转到 Unity 的 质量 设置(编辑 > 项目设置 > 质量)并检查 纹理流 选项来启用它。您可以在 “高级”下的 “纹理导入设置” 中启用“流式 Mip 贴图”。
该系统减少了纹理所需的总内存量,因为它仅加载渲染当前相机位置所需的 Mip Map。否则,Unity 默认加载所有纹理。
纹理流以少量的 CPU 资源来节省可能大量的 GPU 内存。它还会自动降低 Mip Map 级别以保持在用户定义的 内存预算范围内。
您可以使用 Mip Map Streaming API 进行进一步控制。
可寻址资产系统 简化了游戏资产的管理。任何资产,包括场景、预制件、文本资产等,都可以标记为 可寻址 并赋予唯一的名称。然后您可以从任何地方调用该别名。
在游戏及其资产之间添加这一额外的抽象级别可以简化某些任务,例如创建单独的可下载内容包。可寻址资源也使得引用这些资产包变得更容易,无论它们是本地的还是远程的。
从 包管理器安装 Addressables 包。因此,项目中的每个资产或预制件都具有变得“可寻址”的能力。
在 检查器 中选中资产名称下的选项会为其分配一个默认的唯一地址。一旦标记,相应的资产就会出现在 窗口 > 资产管理 > 可寻址 > 组 窗口中。
无论资产托管在其他地方还是存储在本地,系统都会使用 可寻址名称 字符串来定位它。可 寻址预制件 (Addressable Prefab) 在需要时才会加载到内存中,并且在不再使用时自动卸载其相关资源。这篇关于 使用可寻址技术节省内存的 博客文章演示了如何组织 可寻址组 以提高内存利用效率。
看 可寻址:概念简介 快速了解可寻址资产系统如何在您的项目中发挥作用。
我们迄今为止最全面的指南之一收集了 80 多条有关如何针对 PC 和游戏机优化游戏的可行技巧。这些深入的提示由我们的专业成功和Accelerate Solutions工程师创建,将帮助您充分利用 Unity 并提升游戏性能。