mcpField
O
optimize-audio

optimize-audio

github.com/unity-technologies開発57749 回インストール6 日前に更新
リポジトリ

optimize-audio について

メモリ、ロード、再生、DSP の問題を調べる Unity 音声最適化スキルです。変更を提案する前にプロジェクトの数値を確認し、確認ポイントでユーザーの返答を待ってから、適用後の設定を検証します。

主な機能

  1. 01オーディオシステムとリスナーの確認
  2. 02AudioSource とミキサーの調査
  3. 03インポートとロード設定の監査
  4. 04確認ポイント付きの変更手順
  5. 05変更前後の検証

活用シーン

  1. 01音声メモリ使用量の調査
  2. 02DSP やミキサーの CPU 急増の診断
  3. 033D ステレオ再生の問題確認
  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 が本当に存在しないのか Safe Mode で停止しているのかの判別、Editor のコマンドカタログの確認は、まずこのスキルに従ってください。ここで改めて調べる必要はありません。

このスキルでは把握できないことが2つあります。

  • 到達可能な Editor があるだけでは不十分です。特に script eval が必要です。 カタログに表示されることを確認してください。このコマンドがあるかどうかは CLI ではなく Pipeline パッケージのバージョンによって決まるため、正常にインストールされていても利用できない場合があります。見つからない場合は、その旨を伝えて停止してください。
  • インポート設定を変更するために .meta ファイルを直接編集しないでください。 インポーターの値は、実行中の Editor で SaveAndReimport() を呼び出して初めて反映されます。そのため、Editor に接続できない場合は停止してください。メタデータを直接編集してはいけません。

C# は unity command script eval --caller plugin --skill optimize-audio --code '<snippet>' で実行します。パラメーターの形式は推測せず、unity command --format json で確認してください。unity command のタイムアウトはデフォルトで30秒です。

script eval への C# の渡し方

script eval がコンパイルするのはファイルではなくステートメントブロックです。このため、次の2点に注意してください。どちらも警告ではなくコンパイルエラーになります。

  • 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 を検索し、リスナーが正確に1つ存在することを確認します。リスナーが複数あると空間化が正しく行われず、リスナーが1つもないと無音になります。
  4. 続行する: プラットフォームとリスナーの状態を確認してから次に進んでください。

2. 現在の状態を評価する

変更を推奨する前に、観測可能なデータを収集します。

  1. すべての AudioSource を見つけます: resources/audio-import-api.md のシーンコンポーネント検索レシピを使用して、UnityEngine.AudioSource を検索します。各結果について、プロパティをまとめて読み取るために script eval を1 回呼び出します。resources/audio-import-api.md の一括読み取りレシピを参照してください。
  2. ミキサーの構成を確認します: 事前確認でミキサーが見つかった場合は、script eval を使用して AudioMixer の公開パラメーターとグループ数を読み取ります。グループ数が約 8 を超える場合や、Master グループにエフェクトがある場合は、直ちに注意が必要です。
  3. DSP バッファーサイズを確認します: resources/audio-import-api.md の DSP バッファーレシピを使用して、バッファーサイズを読み取ります。推奨値については、resources/platform-settings.md の DSP Buffer Size Guidelines を参照してください。
  4. 変更を加える前に、調査結果を報告します: 検出されたすべてのソース、リスナー数、ミキサーの階層の深さを要約してユーザーに伝えます。すぐに対処すべきリスク(例:spatialBlend = 1 のステレオクリップ、1 MB を超えるクリップの Decompress On Load、Master グループのリバーブ)にフラグを立てます。

評価を確認してもらうため、先に進む前にユーザーの返答を待ちます。

3. リクエストを把握する

ユーザーのニーズに応じて、適切なセクションに案内します。

ユーザーの発言セクション
「オーディオメモリが多すぎる」/「メモリプロファイラーにオーディオが表示される」セクション 4 — インポート設定の監査
「読み込みが遅い」/「デコード時に停止する」セクション 4 — 読み込みタイプの確認
「DSP のスパイク」/「ミキサーの CPU 使用率」/「オーディオの CPU 使用率が高い」セクション 4B — ミキサーの監査
「3D サウンドがおかしい」/「左チャンネルしか再生されない」/「3D でステレオ」セクション 4A — Force To Mono と空間設定
「音質に問題がある」/「音声がひどい」/「Vorbis の音が割れる」セクション 4C — 圧縮品質の調整
「モバイルのオーディオでバッテリーを消費する」/「モバイルのメモリ」セクション 4D — モバイルのサンプルレートのオーバーライド
「すべてのクリップのインポート設定を変更する」/「オーディオ設定を一括変更する」セクション 4 — インポート設定の一括監査
「ストリーミング」/「バックグラウンド読み込み」/「Addressables のオーディオ」セクション 4E — ストリーミングと非同期読み込み

症状がはっきりしない場合は、「問題はオーディオのメモリ使用量、DSP の CPU スパイク、オーディオ再生品質のどれですか?」と尋ねます。

4. 主な診断ワークフロー

セクション 2 の調査結果をもとに、該当するサブセクションを判断します。複数のサブセクションが同時に該当する場合もあります。

4A. Force To Mono と空間設定

spatialBlend > 0(3D 位置のサウンド)であるすべての AudioSource について、次の手順を実行します。

  1. クリップのチャンネル数を確認します: script eval を使用して audioSource.clip.channels を読み取ります。channels == 2 かつ spatialBlend == 1 の場合、左チャンネルしか再生されません。これは仕様ではなくバグです。
  2. Force To Mono を推奨します: resources/audio-import-api.md のインポーター読み取りレシピを使用して現在の設定を確認し、Force To Mono レシピを使用して適用します。
  3. 適用して再インポートします: 変更前後のチャンネル数をユーザーに報告します。
  4. 空間ブレンドを確認します: script eval を使用して、audioSource.spatialBlend が 1.0(完全な 3D)であり、audioSource.rolloffMode が適切なカーブに設定されていることを確認します。
4B. AudioMixer の監査
  1. グループの階層数を測定する: script eval を使用してミキサーのグループツリーをたどり、階層数を数えます。3階層(Master → SFX / Music / Voice → サブバス)を超えると、子グループが無音の場合でも、毎フレームのルーティング処理の負荷が増加します。

  2. 無音グループのエフェクトを確認する: script eval を使用して、各グループのエフェクトリストを取得します。AudioReverbFilter などのエフェクトは、そのグループにルーティングされる AudioSource がなくても、DSP の処理をフルコストで実行します。

  3. 親グループの SFX Reverb に注意する: これは最も負荷の高い組み込みエフェクトです。Master または上位グループで見つかった場合は、明示的に報告します。

  4. 推奨事項をユーザーに提示する:

    • アクティブなソースがないグループのエフェクトを削除するか、バイパスします。
    • 実行時にエフェクトを切り替えるのではなく、スナップショットを使用してミックス状態(戦闘/探索/一時停止)を切り替えます。
    • 不要なサブバスを整理し、ソースをより浅い階層の親グループに振り向けます。

    ミキサーの変更を適用する前に、ユーザーの承認を待ちます。

  5. DSP バッファーサイズを確認する: Pre-Flight の bufferLength が非常に小さい(< 256)場合は、増やすことを推奨します。resources/platform-settings.md の DSP バッファーサイズのガイドラインを参照してください。

4C. 圧縮品質の調整
  1. 現在の圧縮形式を読み取る: resources/audio-import-api.md のインポーターレシピを読み取る手順を使用し、ユーザーが報告したクリップの compressionFormat と quality を読み取ります。
  2. プラットフォーム別のマトリックスを適用する: プラットフォームごとの推奨事項については、resources/platform-settings.md の圧縮形式マトリックスを参照してください。
  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 のサンプルレートの推奨事項を参照してください。
  4. 削減量を報告する: サンプルレートを半分にすると、PCM メモリの使用量も半分になります。変更した各クリップについて、推定削減量を報告します。
4E. ロードタイプとストリーミング
  1. クリップごとにロードタイプを監査する: script eval を使用して、セクション 2 で見つかった各クリップの clip.loadType を読み取ります。
  2. 判定ルールを適用する: resources/platform-settings.md のロードタイプ判定表を参照してください。
  3. 不一致に注意する: resources/platform-settings.md のロードタイプ不一致フラグを参照してください。2種類の不一致をどちらもユーザーに報告します。
  4. ストリーミングの各クリップに 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(ステレオはメモリを 2 倍消費します)と clip.frequency(モバイル向けの高いサンプルレートはメモリを浪費します)を確認します。Force To Mono やサンプルレートのオーバーライドを適用します。
AudioMixer の CPU 使用率が急増する — DSP スレッドの負荷が高い
  1. ミキサーアセットの検索手順を使って、ミキサーグラフが存在することを確認します。
  2. script eval を使用して、すべてのグループと、それらにアタッチされたエフェクトを一覧表示します。上位レベルのグループにリバーブ、コーラス、EQ が設定されていないか確認します。
  3. 負荷の高いエフェクトを、ソースの再生中にのみ有効になるリーフグループに移動します。
  4. メニュー中のリバーブをバイパスするなど、エフェクトが聞こえないゲームプレイ状態では、スナップショットを使ってエフェクトチェーンをバイパスします。
  5. DSP バッファーが小さい(64 または 128 サンプル)場合は、サイズを大きくします。リソース/プラットフォーム設定の「DSP Buffer Size Guidelines」を参照してください。
ダイアログで Vorbis の品質劣化が発生する
  1. defaultSampleSettings.compressionFormat == AudioCompressionFormat.Vorbis であることを確認します。
  2. defaultSampleSettings.quality を確認します。デフォルトは 0.5 で、音声では劣化が聞き取れることがよくあります。0.7〜0.85 に上げてください。
  3. iOS では、Vorbis ではなく AAC に切り替えます(ハードウェアデコードに対応し、同等のビットレートでより高音質です)。
  4. ソースファイルが可逆形式(WAV または AIFF)であることを確認します。MP3 のソースでは、Unity が再エンコードする前に失われた品質を復元できません。
AudioListener の数がちょうど 1 ではない
  • リスナーが 0 個: すべてのオーディオが無音になります。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 では、バックグラウンド読み込みの Streaming ではなく、初回再生時に同期読み込みする CompressedInMemory に切り替えます。

7. 完了

監査または最適化が終わったら、次のことを行います。

  • 変更した設定をすべて、変更前と変更後の値を示してまとめます。
  • 引き続き対応が必要なクリップやグループを列挙します(例:削減効果を確認するため、デバイス上での測定が必要なクリップ)。
  • 実行時のメモリ測定が必要な場合は、実行時のバイトコストが最も大きい AudioClip を報告する Memory Profiler パッケージを案内します。
  • 監査後もミキサーの CPU 使用率が高い場合は、DSP スレッドのプロファイリングに Unity Profiler の Audio モジュールを案内します。

詳細なリファレンス

関連項目

  • Memory Profiler パッケージ — 実行時のバイトコストが最も大きい AudioClip を特定します。
  • Unity Profiler の Audio モジュール — DSP の CPU マーカーとフレーム時間の予算を確認します。
  • audio-setup-mixers — ミキサーの作成と、Audio Sources からグループへのルーティングを行います。

コメント