mcpField
O
optimize-audio

optimize-audio

github.com/unity-technologies开发1.2k5.9k 次安装1 天前更新
代码仓库

关于 optimize-audio

面向 Unity 开发者的音频导入、播放和混音器性能诊断技能。它先收集项目状态,在指定检查点等待确认,并通过测量和设备构建验证更改。

主要功能

  1. 01检查音频源、监听器和混音器
  2. 02审查导入与加载设置
  3. 03诊断空间音频和声道问题
  4. 04检查混音器 DSP 开销
  5. 05调整压缩与采样率
  6. 06重新导入后验证更改

适用场景

  1. 01调查音频内存或加载时间问题
  2. 02诊断混音器 CPU 峰值
  3. 03修正用于 3D 音频的立体声片段
  4. 04调整对白压缩质量

MCP 相关

该技能通过已连接的 Unity Editor 中的 `eval` 运行 C#,并使用 `unity-cli` 技能所述的 Unity CLI 操作路径。它是工作流技能,不是 MCP 服务。

安装

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

$npx skills add https://github.com/unity-technologies/skills --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 与卡在 Safe Mode 中的 Editor,以及发现 Editor 的命令目录。请先按该技能操作;不要在此重新推导这些内容。

有两件事需要你自行确认:

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

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

将 C# 传递给 eval

eval 编译的是语句块,而不是文件。这会带来两种情况,都会导致编译错误,而不是警告:

  • **不能使用 using 指令。**编译器会将 using UnityEngine; 视为资源释放语句并拒绝它(CS0210)。
  • **类型必须使用完全限定名。**裸写 AssetDatabase 或 AudioImporter 无法解析(CS0246 / CS0103);裸写 Object 则会与 object 混淆(CS0104)。

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

1. 预检:检测音频系统

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

  1. **检测平台和采样率:**使用 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。对于每个结果,使用一次 eval 调用批量读取属性——参见 resources/audio-import-api.md 中的批量读取方法。
  2. 检查混音器拓扑: 如果预检时找到混音器,使用 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 的 AudioSource(3D 定位声音):

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

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

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

  4. 向用户提出建议:

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

    在应用混音器更改前,等待用户批准。

  5. 验证 DSP 缓冲区大小: 如果预检中的 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. 审计每个音频片段的加载类型: 使用 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. 重新读取音频片段统计信息: 使用 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. 使用 eval 列出所有组及其附加效果。检查高层级组是否使用了混响、合唱或均衡器。
  3. 将开销较大的效果移到叶子组,这些组仅在音源播放时处于活动状态。
  4. 在听不到效果的游戏状态下,使用快照绕过效果链(例如,在菜单期间绕过混响)。
  5. 如果 DSP 缓冲区较小(64 或 128 个采样),请调高它——参见 resources/platform-settings.md 中的 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 数量不等于 1
  • 没有侦听器: 所有音频都会静音。使用 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 包;该包会报告运行时字节开销最大的 AudioClip。
  • 如果审计后混音器 CPU 占用仍然较高,请向其推荐 Unity Profiler 的 Audio 模块,用于分析 DSP 线程。

详细参考

另请参阅

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

评论

支持 Markdown