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