二、Audio 导入设置检查与优化
Unity 性能优化初级篇(二):Audio 导入设置检查与优化
本文整理自视频:《Unity性能优化》第壹节——静态资源优化(1):Audio 导入设置检查与优化。
本文重点讨论 Unity 音频资源的导入设置、UPR AssetChecker 检查流程,以及如何在内存、CPU、包体和音质之间取得平衡。
文中的检查数量、优化结果和具体阈值均来自视频示例项目。除非特别说明,不应将这些数据理解为 Unity 的通用规则。
一、Audio 导入设置在性能优化中的位置
Unity 中的音频优化,首先发生在 Assets 工作流中,而不是从运行时脚本开始。
一个音频文件从源文件到最终运行时数据,大致经过以下流程:
在 Project 窗口中选中音频资源后,Inspector 中的 Audio Clip Import Settings 会影响:
- 音频的声道数量;
- 采样率;
- 平台压缩格式;
- 运行时加载方式;
- 是否预加载音频数据;
- 运行时内存占用;
- 播放和解码产生的 CPU 开销;
- 最终安装包大小。
需要特别区分导入设置和运行时资源管理:
| 操作 | 所处阶段 | 作用 |
|---|---|---|
| 修改 Audio Clip Import Settings | 编辑器导入阶段 | 决定音频如何转码和打包 |
| 设置 AudioSource.volume | 运行时 | 调整播放音量 |
| 调用 AudioSource.Stop() | 运行时 | 停止播放 |
| 调用 AudioClip.LoadAudioData() | 运行时 | 加载音频数据 |
| 调用 AudioClip.UnloadAudioData() | 运行时 | 卸载音频数据 |
| 释放 Addressables 或 AssetBundle 引用 | 运行时资源管理 | 释放资源系统持有的引用 |
源文件扩展名也不等于设备上的最终格式。Unity 会根据构建目标和平台覆盖设置重新编码音频,因此优化时应检查导入后的大小、压缩格式和运行时内存,而不能只看原始文件大小。
二、使用 UPR AssetChecker 检查音频资源
为什么需要自动检查
小型项目可以手动逐个检查 AudioClip Inspector,但实际项目中的音频通常分散在多个目录,并由不同成员、工具和时间批次导入。
手工检查容易出现:
- 漏掉部分目录;
- 同类资源使用不同压缩格式;
- Android 和 iOS 没有设置合适的平台覆盖;
- 短音效错误地使用 Streaming;
- 长音乐被设置为 Decompress On Load;
- 本应单声道的音频保留了多声道数据;
- 采样率和 Quality 缺少统一规范。
UPR AssetChecker 可以独立于 Unity Editor 扫描项目资源,根据规则生成报告。其 Audio 类规则可覆盖平台压缩格式、Load Type 和 Force To Mono 等检查项。
基本检查流程
- 下载并解压 AssetChecker;
- 使用命令行查看帮助;
- 生成或准备检查配置;
- 指定 Unity 项目路径执行检查;
- 查看本地报告,或上传到 UPR 网站;
- 按规则和资源路径逐项复核;
- 修改导入设置后重新导入、构建并测试。
基本命令:
assetcheck.exe --project="C:\UnityProjects\MyProject" --projectId="<UPR项目ID>"只检查音频目录:
assetcheck.exe --project="C:\UnityProjects\MyProject" --includePaths="Assets/Audio"排除第三方或编辑器资源:
assetcheck.exe --project="C:\UnityProjects\MyProject" --excludePaths="Assets/ThirdParty,Assets/Editor"检查结果可以从本地的 rule_report.yaml 查看,也可以将 assetcheck_result.json 上传到 UPR 网站查看可视化报告。完整参数以 UPR Unity AssetChecker 官方文档为准。
检查建议不是自动修改命令
AssetChecker 的规则用于发现潜在问题,但“触发规则”不等于“必须修改”:
- Force To Mono 可能破坏立体声和空间信息;
- Streaming 可以降低长音频内存,但会增加流式读取和解码开销;
- 降低采样率可以减少数据量,也可能损失高频细节;
- 更换压缩格式会同时改变音质、包体和运行时 CPU;
- 同一种音频设置不可能适合音乐、语音、环境声和短音效。
即使使用支持自动修复的规则,也应先保留版本记录,再抽样试听、重新构建并在目标设备测试。
三、Force To Mono 的适用边界
Force To Mono 会把多声道音频混合为单声道后再打包。相比双声道,单声道通常可以减少数据量,但实际收益还取决于压缩格式、采样率、音频长度和平台转码结果。
适合评估单声道的音频
- 不依赖左右声道差异的短音效;
- 脚步声、碰撞声、点击声;
- 通过 3D AudioSource 作为单点声源播放的音效;
- 左右声道内容基本相同的资源;
- 不需要保留立体声宽度的提示音。
即使音频最终用于 3D 空间播放,源文件也不一定需要保留双声道。空间化播放和源文件声道数量是两个需要分别考虑的问题。
不应直接转成单声道的音频
- 音乐;
- 具有明显左右声道编排的环境声;
- 需要保留立体声宽度的 UI 或过场音频;
- 两个声道包含不同内容的语音或效果;
- Ambisonic 音频;
- 依赖声道差异表达方向和空间关系的音频。
因此,Force To Mono 应按用途分类并逐项试听,不能对整个 Assets/Audio 目录盲目开启。Unity 6.6 对该选项的定义和相关字段可参考 Audio Clip Import Settings。
四、平台压缩格式如何选择
Unity 导入音频后,会根据构建目标和 Compression Format 进行转码。同一源文件可以在 Android 和 iOS 使用不同的平台覆盖设置。
常见格式的取舍如下:
| 格式 | 典型特点 | 适合场景 | 主要代价 |
|---|---|---|---|
| PCM | 未压缩,播放处理简单 | 对延迟或质量敏感的短音效 | 文件和内存占用较大 |
| ADPCM | 固定压缩比,解码成本较低 | 脚步、碰撞、武器等短促且频繁的音效 | 平滑音乐或环境声可能出现明显伪影 |
| Vorbis/MP3 | 压缩率高,可调节 Quality | 中长音效、语音、音乐 | 播放时需要解码,增加 CPU 开销 |
Unity 6.6 文档说明,ADPCM 相对 PCM 提供约 3.5 倍的固定压缩比;Vorbis/MP3 通常能获得更高压缩率,但需要用 Quality 平衡音质和体积。Audio file compression in Unity
可以按用途建立初始方案:
| 音频用途 | 初步方案 | 仍需验证 |
|---|---|---|
| 短促 UI 音效 | PCM 或 ADPCM | 播放频率、响应速度和内存 |
| 大量脚步与碰撞声 | ADPCM | 是否出现可闻压缩伪影 |
| 中长语音 | Vorbis/MP3 | 解码 CPU 与语音清晰度 |
| 背景音乐 | Vorbis/MP3 + Streaming | 首播延迟和流式开销 |
| 高保真短音频 | PCM | 包体和内存是否可接受 |
| Ambisonic 或特殊空间音频 | 按空间音频需求设置 | 不可直接 Force To Mono |
这只是起始分类,最终设置必须通过目标平台试听和 Profiler 验证。
五、Sample Rate Setting 的选择
采样率决定单位时间内保存多少个采样点。较高采样率通常能保留更多高频细节,也会增加 PCM/ADPCM 数据量和处理量。
Audio Clip Import Settings 中常见的采样率选项包括:
| 选项 | 含义 |
|---|---|
| Preserve Sample Rate | 保留源音频采样率 |
| Optimize Sample Rate | 根据音频频率内容自动优化 |
| Override Sample Rate | 手动指定采样率 |
具体选项的可用性会受到压缩格式、平台和 Unity 版本影响。
22050 Hz 不是移动端通用规则
视频案例将移动端音频设置为 22050 Hz,这是该项目采用的优化经验,并非所有移动项目都应遵守的硬规则。
较低采样率可能适合大量短音效和高频内容不重要的提示音,但音乐、高质量环境声、重要语音以及高频明显的机械声或自然声可能需要更高采样率。
更稳妥的做法是:
- 先使用 Optimize Sample Rate 获取自动分析结果;
- 按音乐、语音、环境声和短音效分类;
- 对低价值、低频内容较多的音效评估 Override Sample Rate;
- 对音乐和重要语音保留足够采样率;
- 在目标设备试听,并记录内存和包体变化。
六、三种 Load Type 的内存与 CPU 取舍
AudioClipLoadType 决定运行时如何加载音频数据,主要分为 Decompress On Load、Compressed In Memory 和 Streaming。AudioClipLoadType 官方 API
Decompress On Load
音频加载时完成解压,播放阶段的解码成本较低。
优点:
- 播放响应快;
- 播放时 CPU 开销较低;
- 适合短而频繁播放的音效。
缺点:
- 加载时可能产生峰值;
- 解压后占用更多内存;
- 不适合大量长音频同时加载。
Unity 文档提醒,Vorbis 音频解压到内存后可能约为压缩状态的十倍,ADPCM 则约为 3.5 倍;具体结果仍应以所用 Unity 版本和 Memory Profiler 实测为准。
Compressed In Memory
完整音频以压缩形式保留在内存,播放时解码。
优点:
- 比 Decompress On Load 节省内存;
- 不需要像 Streaming 一样持续读取存储;
- 适合中等长度、播放频率不固定的音效或语音。
缺点:
- 播放时产生解码 CPU 开销;
- 大量音频同时播放时可能增加混音线程压力。
Compressed In Memory 的解码成本可以在 Profiler Audio 模块的 DSP CPU 中观察。
Streaming
从存储持续读取压缩数据,并在运行时逐步解码,通常只保留一小段缓冲。
优点:
- 适合长时间播放的音乐和语音;
- 不需要把完整音频解压进内存;
- 可以显著降低长音频的常驻内存。
缺点:
- 产生流式读取、线程调度和解码开销;
- 可能出现首播延迟;
- 不适合大量极短音效;
- 受目标平台存储访问性能影响。
Unity 文档指出,每个 Streaming Clip 即使没有加载音频数据,也会产生约 200 KB 的流式缓冲开销。这个数字不能和视频中的经验阈值混为一谈:
- “小于 200 KB 的音频不能使用 Streaming”不是 Unity 的通用规则;
- “Streaming Clip 本身存在约 200 KB 开销”是特定版本官方文档给出的实现提示。
真正的判断依据应是播放时长、播放频率、内存预算、平台存储性能和首播需求,而不是只看压缩后的文件大小。
三种方式对比
| Load Type | 内存占用 | 播放时 CPU | 首次播放 | 典型用途 |
|---|---|---|---|---|
| Decompress On Load | 高 | 低 | 较快 | 高频短音效 |
| Compressed In Memory | 中 | 中 | 依赖解码 | 中等长度音效、语音 |
| Streaming | 低 | 有流式开销 | 可能有延迟 | 长音乐、长语音 |
一个项目通常需要混合使用三种方式,而不是全部设置成同一种 Load Type。
七、停止播放不等于卸载音频
视频提出“静音时销毁 AudioSource”以释放资源,但这不能直接当作 Unity 的通用规则。
需要区分:
- AudioSource.volume = 0:仅让声音听不见;
- AudioSource.Stop():停止当前播放;
- 禁用或销毁 AudioSource:改变播放组件生命周期;
- AudioClip.UnloadAudioData():尝试卸载 AudioClip 的音频数据;
- 释放 Addressables 或 AssetBundle:释放资源系统持有的引用。
把音量设为零、调用 Stop 或禁用 AudioSource,都不等于 AudioClip 已经从内存中卸载。销毁 AudioSource 也不保证资源系统没有其他引用。
对于背景音乐或常驻环境声,静音通常应由 AudioMixer 或音量控制完成,不宜每次静音都销毁管理播放状态的 AudioSource。对于一次性音效,可以在播放结束后归还 AudioSource 对象池或销毁临时对象;只有确认音频不再使用时,才卸载 AudioClip 数据并释放对应 Addressables/AssetBundle 句柄。
加载资源
→ 获取 AudioSource
→ 播放
→ 停止播放
→ 归还对象池或销毁临时对象
→ 确认无其他使用者
→ 卸载 AudioClip 数据
→ 释放资源系统句柄具体 API 与版本行为以 Unity AudioClip API 为准。
八、视频案例中的优化结果
视频案例使用 UPR AssetChecker 检查项目中的音频资源。
检查结果
| 项目 | 视频案例观测值 |
|---|---|
| 检查音频数量 | 84 个 |
| 被报告建议改进的资源或检查项 | 75 个 |
视频描述为:共检查 84 个音频资源,其中 75 个资源或检查项被报告建议改进。具体计数口径以当时的报告版本为准,本文不将其解释为 75 条彼此独立的建议。
检查重点包括:
- 哪些音频触发 Force To Mono 建议;
- 哪些音频使用了不合适的 Load Type;
- Android 和 iOS 是否设置了平台压缩格式;
- 是否存在体积较大的音频;
- 采样率是否超过内容实际需要;
- 音乐和短音效是否使用了相同的统一设置。
优化后观测值
| 指标 | 优化后或变化量 |
|---|---|
| 音频内存 | 约 6.9 MB |
| 音频内存变化 | 比优化前减少近 70 MB |
| CPU 负载 | 增加约 2% |
| 包体大小 | 减少约 16 MB |
以上全部是视频示例项目的观测值,不代表其他 Unity 项目能够获得相同收益。
案例中,内存和包体下降的同时,CPU 负载增加约 2%。这说明压缩、解码和内存之间存在真实权衡:更小的内存占用往往需要承担更多运行时解码成本。
这组结果不能推出:
- 所有音频都应该使用 22050 Hz;
- 所有音频都应该 Force To Mono;
- 小于或大于 200 KB 就必须使用某一种 Load Type;
- 所有长音频都一定应该 Streaming;
- 其他设备也只会增加 2% CPU;
- 其他项目也能减少近 70 MB 内存和 16 MB 包体。
优化后必须重新确认:
- 音乐和语音是否出现压缩伪影;
- 立体声与空间感是否被破坏;
- 首次播放是否产生延迟;
- 多个音效同时播放时是否出现 CPU 峰值;
- 场景切换是否出现加载卡顿;
- Android 和 iOS 是否都能正常播放。
九、Audio 导入设置检查清单
资源分类
Force To Mono 与压缩格式
Sample Rate 与 Load Type
生命周期与验证
总结
Audio 优化不是把所有资源压缩到最小,而是在音质、内存、CPU、包体和加载体验之间取舍。
一套可靠流程通常是:
资源分类
→ UPR AssetChecker 扫描
→ 复核 Force To Mono
→ 选择平台压缩格式
→ 调整采样率
→ 选择 Load Type
→ 检查资源生命周期
→ 真机试听与 Profiler 验证Force To Mono、22050 Hz、200 KB 和“静音时销毁 AudioSource”都不能脱离项目直接变成通用规则。真正有效的音频优化,应同时满足:
- 包体和内存确实下降;
- CPU 增量在目标设备可接受;
- 音乐、语音和音效质量满足需求;
- 首次播放和场景切换没有明显卡顿;
- Android、iOS 等目标平台行为正常;
- 停止、卸载和重新加载的生命周期正确。
