mcpField
O
optimize-audio

optimize-audio

github.com/unity-technologies开发58154 次安装6 天前更新
代码仓库

关于 optimize-audio

这项 Unity 音频优化技能面向排查内存、加载、播放或 DSP 问题的开发者。它先收集项目数据再提出修改建议,在检查点等待用户审阅,并在修改后验证设置。

主要功能

  1. 01检查音频系统与监听器
  2. 02检查 AudioSource 和混音器
  3. 03审查导入与加载设置
  4. 04按检查点执行修改
  5. 05修改前后验证

适用场景

  1. 01排查音频内存占用
  2. 02诊断 DSP 或混音器 CPU 峰值
  3. 03检查 3D 立体声音频播放问题
  4. 04调整音频压缩或流式加载

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unity-technologies/unity-agent-plugin --skill optimize-audio

安装后在 Claude Code 中输入/optimize-audio确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

SECURITY.md
resources/
audio-import-api.md
platform-settings.md

详细介绍

关键规则

  • 向用户报告发现的问题之前,不要进行任何更改
  • 严格按顺序执行步骤;切勿跳步
  • 在每个 WAIT 检查点停止,并等待用户回复后再继续
  • 质量比速度更重要:每次更改前后都要测量
  • 始终在设备构建中验证结果;Editor 音频统计数据仅供参考

0. 设置执行路径

以下每个 C# 步骤都通过 Unity CLI 在运行中的 Editor 内执行。unity-cli 技能负责引导你完成这些步骤——安装 CLI、确认 Editor 已连接、添加项目的 com.unity.pipeline 包、区分真正缺失的 Editor 和卡在安全模式中的 Editor,以及发现 Editor 的命令目录。请先按该技能的说明操作;不要在此重新推导这些内容。

有两件事它无法替你确认:

  • **你需要的是 script eval,而不仅仅是能连接到 Editor。**请确认它出现在命令目录中。它是否存在取决于 Pipeline 包的版本,而非 CLI,因此即使安装正常,也可能缺少该命令——如果找不到,请说明并停止。
  • **不要手动编辑 .meta 文件来更改导入设置。**导入器的值只有通过运行中的 Editor 调用 SaveAndReimport() 才会生效,因此 Editor 无法连接时应停止,而不是直接编辑元数据。

使用 unity command script eval --caller plugin --skill optimize-audio --code '<snippet>' 运行 C#。请通过 unity command --format json 查看参数格式,不要自行假设。unity command 默认超时时间为 30 秒。

向 script eval 传递 C#

script eval 编译的是语句块,而非文件。这会导致以下两种情况;两者都会引发编译错误,而非警告:

  • **不能使用 using 指令。**编译器会将 using UnityEngine; 识别为资源释放语句并拒绝它(CS0210)。
  • **类型必须使用完全限定名。**直接使用 AssetDatabase 或 AudioImporter 无法解析(CS0246 / CS0103),直接使用 Object 则会与 object 产生歧义(CS0104)。

resources/audio-import-api.md 中的操作示例都使用了完全限定名,因此可直接传递给 script eval。

1. 预检:检测音频系统

在进行任何其他操作之前,先确认音频环境:

  1. **检测平台和采样率:**使用 script eval 读取 EditorUserBuildSettings.activeBuildTarget 和 AudioSettings.outputSampleRate。输出采样率会影响覆盖音频片段采样率是否确实能节省内存。
  2. **检测 AudioMixer 是否存在:**使用 resources/audio-import-api.md 中的混音器资源查询示例,检查是否存在混音器图。如果不存在,请注明路由和效果的开销无需考虑。
  3. **检测 AudioListener:**使用 resources/audio-import-api.md 中的场景组件查询示例查询 UnityEngine.AudioListener,确认场景中恰好存在一个监听器。多个监听器会导致空间化不正确;没有监听器则会导致无声。
  4. 仅在确认平台和监听器状态后,继续操作。

2. 评估当前状态

在建议任何更改之前,先收集可观察的数据:

  1. 查找所有 AudioSource: 使用 resources/audio-import-api.md 中的场景组件查询方法,查询 UnityEngine.AudioSource。对每个结果,使用一次 script eval 调用批量读取属性,参阅 resources/audio-import-api.md 中的批量读取方法。
  2. 检查混音器拓扑: 如果在预检中发现了混音器,使用 script eval 读取 AudioMixer 的暴露参数和组数。组数超过约 8,或 Master 组上有特效,都应立即标记为风险。
  3. 检查 DSP 缓冲区大小: 使用 resources/audio-import-api.md 中的 DSP 缓冲区方法读取缓冲区大小。有关建议值,请参阅 resources/platform-settings.md 中的 DSP 缓冲区大小指南。
  4. 在进行更改之前报告发现: 向用户总结检测到的所有音源、监听器数量和混音器层级。标记任何即时风险(例如,spatialBlend = 1 的立体声音频片段、大小 > 1 MB 且采用 Decompress On Load 的音频片段、Master 组上的混响)。

等待用户查看评估结果后再继续。

3. 了解请求

根据用户的需求,转到相应的部分:

用户表示路径
“音频内存过高” / “内存分析器显示音频”第 4 节 — 导入设置审查
“加载时间过长” / “解压卡顿”第 4 节 — 加载类型审查
“DSP 峰值” / “混音器 CPU” / “音频 CPU 占用高”第 4B 节 — 混音器审查
“3D 声音不对” / “只有左声道播放” / “3D 中的立体声”第 4A 节 — 强制转为单声道 + 空间设置
“音质失真” / “语音听起来很糟” / “Vorbis 噼啪声”第 4C 节 — 压缩质量调整
“移动设备音频耗电” / “移动设备内存”第 4D 节 — 移动设备采样率覆盖
“为所有音频片段设置导入设置” / “批量音频设置”第 4 节 — 批量导入审查
“流式传输” / “后台加载” / “Addressables 音频”第 4E 节 — 流式传输与异步加载

如果问题症状不明确,请询问:“问题是音频内存占用、DSP CPU 峰值,还是音频播放质量?”

4. 主要诊断工作流

根据第 2 节的发现,确定适用的小节。可能同时适用多个小节。

4A. 强制转为单声道和空间设置

对于 spatialBlend > 0(定位为 3D 声音)的任何 AudioSource:

  1. 检查音频片段声道数: 使用 script eval 读取 audioSource.clip.channels。如果 channels == 2 且 spatialBlend == 1,则只会播放左声道——这是一个错误,而非功能特性。
  2. 建议强制转为单声道: 使用 resources/audio-import-api.md 中读取导入设置的方法检查当前设置,然后使用强制转为单声道的方法应用该设置。
  3. 应用并重新导入: 向用户报告更改前后的声道数。
  4. 验证空间混合: 使用 script eval 确认 audioSource.spatialBlend 为 1.0(完整 3D),且 audioSource.rolloffMode 设置为适当的衰减曲线。
4B. AudioMixer 审核
  1. 测量组深度: 使用 script eval 遍历混音器的组树并统计层级。超过 3 层(Master → SFX / Music / Voice → 子总线)会增加每帧的路由开销,即使子组处于静音状态也一样。

  2. 检查静音组上的效果: 使用 script eval 查询每个组的效果列表。即使没有 AudioSource 路由到该组,AudioReverbFilter 等效果仍会以完整开销运行 DSP。

  3. 标记父组上的 SFX Reverb: 这是开销最高的内置效果。如果在 Master 或高层级组上发现此效果,请明确标记。

  4. 向用户提出建议:

    • 移除或旁通没有活动音源的组上的效果。
    • 使用快照切换混音状态(战斗/探索/暂停),而不是在运行时切换效果。
    • 扁平化不必要的子总线;将音源重定向到层级更浅的祖先组。

    等待用户批准混音器更改后再应用。

  5. 验证 DSP 缓冲区大小: 如果 Pre-Flight 中的 bufferLength 很小(< 256),建议增大该值——参见 resources/platform-settings.md 中的 DSP Buffer Size Guidelines。

4C. 压缩质量调优
  1. 读取当前压缩格式: 使用 resources/audio-import-api.md 中的读取导入器配方,读取用户报告的音频片段的 compressionFormat 和 quality。
  2. 应用平台矩阵: 各平台的建议参见 resources/platform-settings.md 中的 Compression Format Matrix。
  3. 警告有损源文件: 使用 resources/audio-import-api.md 中的有损源文件检查配方。如果原始文件是 MP3,请告知用户:Unity 重新编码后,有损源文件的质量损失将无法恢复。建议使用 WAV 或 AIFF 源文件。
4D. 移动平台采样率覆盖
  1. 识别移动平台目标上的 SFX 音频片段: 使用 UnityEngine.AudioSource 的场景组件查询配方,并筛选出非音乐、非对白的音频片段。
  2. 读取当前采样率设置: 使用 resources/audio-import-api.md 中的读取导入器配方,读取每个音频片段的 sampleRateSetting 和 sampleRateOverride。
  3. 应用移动平台覆盖: 使用 resources/audio-import-api.md 中的采样率覆盖配方。各使用场景的采样率参见 resources/platform-settings.md 中的 Sample Rate Recommendations。
  4. 报告节省量: 采样率减半,PCM 内存开销也会减半。报告每个已更改音频片段的预估节省量。
4E. 加载类型与流式传输
  1. 审核每个音频片段的加载类型: 使用 script eval 读取第 2 节中每个音频片段的 clip.loadType。
  2. 应用判定规则: 参见 resources/platform-settings.md 中的 Load Type Decision Table。
  3. 标记不匹配项: 参见 resources/platform-settings.md 中的 Load Type Mismatch Flags。向用户报告这两类不匹配情况。
  4. 为任何 Streaming 音频片段应用 Load In Background——使用 resources/audio-import-api.md 中的 Load In Background 配方。

5. 验证

每次更改导入设置或混音器后:

  1. 重新读取剪辑统计信息: 使用 script eval 重新读取 clip.loadType、clip.channels、AudioSettings.outputSampleRate 和导入器的 compressionFormat,确认重新导入后更改已生效。
  2. 确认 AudioSource 路由: 使用针对 UnityEngine.AudioSource 的场景组件查询步骤,并在混音器结构调整后确认 audioSource.outputAudioMixerGroup 已按预期分配。
  3. 报告差异: 列出每项已更改设置的更改前后值。读取应用后的导入器值之前,不要假定更改已生效。
  4. 迭代次数限制: 最多进行 3 轮调整和验证,然后暂停并征求用户反馈。

6. 故障排除

3D AudioSource 上的立体声剪辑——只能听到左声道
  1. 确认 audioSource.spatialBlend == 1。
  2. 确认 audioSource.clip.channels == 2。
  3. 在 AudioClip 导入器中启用 forceToMono 并重新导入。导入时,Unity 会将两个声道混合为单声道,并通过 normalize = true 保持音量(保持启用)。
  4. 如果用户不想重新导入:将 audioSource.panStereo = 0 作为运行时临时解决方法,但需提醒这无法恢复立体声信息。
Decompress On Load 剪辑导致内存激增
  1. 确认 clip.loadType == AudioClipLoadType.DecompressOnLoad 且 clip.length 较长(> 5 s)。
  2. 如果是音乐或环境音,切换为 Streaming;如果只偶尔播放,则切换为 CompressedInMemory。
  3. 如果剪辑较短但仍然很大:检查 clip.channels(立体声会使内存占用翻倍)和 clip.frequency(移动平台目标上的高采样率会浪费内存)。应用 Force To Mono 和/或采样率覆盖设置。
AudioMixer CPU 激增——DSP 线程负载过高
  1. 使用混音器资源查询步骤确认混音器图存在。
  2. 使用 script eval 列出所有组及其附加效果。检查高层级组上是否有混响、合唱或均衡器。
  3. 将开销较大的效果移至仅在音源播放时才激活的叶子组。
  4. 在听不到效果链的游戏状态下,使用快照绕过效果链(例如,在菜单期间绕过混响)。
  5. 如果 DSP 缓冲区较小(64 或 128 个采样),请调大;请参阅 资源/平台设置中的 DSP 缓冲区大小指南。
对话中的 Vorbis 音质瑕疵
  1. 确认 defaultSampleSettings.compressionFormat == AudioCompressionFormat.Vorbis。
  2. 确认 defaultSampleSettings.quality;默认值为 0.5,通常会让语音音质明显受损。将其提高到 0.7–0.85。
  3. 在 iOS 上:切换为 AAC 而非 Vorbis(硬件解码,在相同比特率下音质更好)。
  4. 确认源文件为无损格式(WAV 或 AIFF)。MP3 源文件无法恢复 Unity 重新编码前已损失的音质。
AudioListener 数量不恰好为一个
  • 没有监听器: 所有音频都会静音。使用 script eval 将 AudioListener 组件添加到主摄像机:UnityEngine.Camera.main.gameObject.AddComponent<UnityEngine.AudioListener>()。
  • 有多个监听器: Unity 会使用最后一个启用的监听器,导致空间化效果不可预测。使用针对 UnityEngine.AudioListener 的场景组件查询步骤,并禁用除目标监听器之外的所有监听器。
Load In Background 导致首次播放时无声

这是预期行为:首次调用 Play() 时,剪辑尚未完成加载。可通过以下方式缓解:

  1. 在场景开始时预加载剪辑,在需要使用前调用 clip.LoadAudioData()。
  2. 使用 AudioSource.PlayScheduled() 并稍作延迟,以便异步加载完成。
  3. 对于必须立即播放的 AudioSource:切换为 CompressedInMemory(首次播放时同步加载),而不是使用带后台加载的 Streaming。

7. 完成

完成审计或优化后:

  • 总结每项已更改的设置,并列出更改前后的值。
  • 列出仍需处理的剪辑或组(例如,需要在设备上测量以确认节省效果的剪辑)。
  • 如果用户需要测量运行时内存,请指引他们使用 Memory Profiler 包,该包会按运行时字节开销列出最大的 AudioClips。
  • 如果审计后混音器的 CPU 占用仍然很高,请指引他们使用 Unity Profiler 的 Audio 模块分析 DSP 线程。

详细参考

另请参阅

  • Memory Profiler 包 — 按运行时字节开销找出最大的 AudioClips。
  • Unity Profiler 的 Audio 模块 — DSP CPU 标记和帧时间预算。
  • audio-setup-mixers — 创建混音器并将 Audio Sources 路由到组。

评论

支持 Markdown