optimize-audio について
Unity 開発者向けに、オーディオのインポート、再生、ミキサー性能を診断するスキルです。状態を先に調査し、確認ポイントで承認を待ち、測定と実機ビルドで変更を検証します。
主な機能
- 01オーディオソース、リスナー、ミキサーの調査
- 02インポートとロード設定の監査
- 03空間オーディオとチャンネル問題の診断
- 04ミキサーの DSP 負荷確認
- 05圧縮とサンプルレートの調整
- 06再インポート後の変更検証
活用シーン
- 01オーディオのメモリやロード時間の問題調査
- 02ミキサーの CPU スパイク診断
- 033D オーディオでのステレオクリップ修正
- 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.mdresources/audio-import-api.mdplatform-settings.md詳細
重要なルール
- 調査結果をユーザーに報告する前に変更を加えないでください
- 手順は厳密な順序で実行し、先に進んではいけません
WAITチェックポイントごとに停止し、ユーザーの返答を待ってから続行してください- 速度より品質を優先してください。変更の前後には必ず測定してください
- 結果は必ずデバイスビルドで検証してください。Editor のオーディオ統計は参考値にすぎません
0. 実行経路をセットアップする
以下の C# 手順はすべて、Unity CLI を通じて稼働中の Editor 内で実行します。そこまでの準備は unity-cli スキルの担当です — CLI のインストール、接続済み Editor の確認、プロジェクトへの com.unity.pipeline パッケージの追加、Editor が本当に存在しない状態と Safe Mode で停止している状態の判別、Editor のコマンドカタログの確認を行います。まずこのスキルに従い、ここでこれらの手順を再確認しないでください。
次の 2 点については、あなた自身で確認する必要があります。
- 必要なのは、到達可能な Editor だけではなく、特に
evalです。カタログに含まれていることを確認してください。evalの有無は CLI ではなく Pipeline パッケージのバージョンによって決まるため、正常にインストールされていても利用できない場合があります。見つからない場合はその旨を伝え、停止してください。 - インポート設定を変更するために
.metaファイルを直接編集してはいけません。インポーターの値は、稼働中の Editor でSaveAndReimport()を実行した場合にのみ反映されます。そのため、Editor に接続できない場合は停止してください。メタデータを直接編集する指示ではありません。
C# は unity command eval --code '<snippet>' で実行します。パラメーターの形式は推測せず、unity command --format json で確認してください。unity command のタイムアウトはデフォルトで 30 秒です。
C# を eval に渡す
eval がコンパイルするのはファイルではなくステートメントブロックです。これにより、警告ではなくコンパイルエラーになる次の 2 点に注意してください。
usingディレクティブは使えません。 コンパイラーはusing UnityEngine;をリソース破棄ステートメントとして読み取り、拒否します(CS0210)。- 型名は完全修飾する必要があります。
AssetDatabaseやAudioImporterだけでは解決できず(CS0246/CS0103)、Objectだけではobjectと曖昧になります(CS0104)。
resources/audio-import-api.md にあるレシピでは完全修飾名を使っているため、そのまま eval に渡せます。
1. 事前確認:オーディオシステムを検出する
ほかの作業を始める前に、オーディオ環境を確認します。
- プラットフォームとサンプルレートを検出する:
evalを使ってEditorUserBuildSettings.activeBuildTargetとAudioSettings.outputSampleRateを読み取ります。出力サンプルレートによっては、クリップのサンプルレートを上書きしてもメモリを節約できない場合があります。 - AudioMixer の有無を検出する: resources/audio-import-api.md にあるミキサーアセットのクエリレシピを使い、ミキサーグラフが存在するか確認します。存在しない場合は、ルーティングやエフェクトのコストを考慮する必要はないことを記録してください。
- AudioListener を検出する: resources/audio-import-api.md にあるシーンコンポーネントのクエリレシピを使い、
UnityEngine.AudioListenerがちょうど 1 つ存在することを確認します。リスナーが複数あると空間化が正しく行われず、リスナーが 0 個だと無音になります。 - 続行する: プラットフォームとリスナーの状態を確認してから、先に進んでください。
2. 現在の状態を評価する
変更を提案する前に、確認可能なデータを収集します。
- すべての AudioSource を検索します: resources/audio-import-api.md のシーンコンポーネント検索レシピを使用して、
UnityEngine.AudioSourceを検索します。各結果について、1 回のeval呼び出しでプロパティをまとめて読み取ります。詳しくは、resources/audio-import-api.md の一括読み取りレシピを参照してください。 - ミキサーのトポロジーを確認します: Pre-Flight でミキサーが見つかった場合は、
evalを使用して AudioMixer の公開パラメーターとグループ数を読み取ります。グループ数が約 8 を超える場合や、Master グループにエフェクトがある場合は、すぐに注意が必要です。 - DSP バッファーサイズを確認します: resources/audio-import-api.md の DSP バッファーレシピを使用して、バッファーサイズを読み取ります。推奨値については、resources/platform-settings.md の DSP バッファーサイズのガイドラインを参照してください。
- 変更を加える前に調査結果を報告します: 検出されたすべてのソース、リスナー数、ミキサーの階層の深さをユーザーに要約して伝えます。すぐに対処が必要なリスク(例:
spatialBlend = 1のステレオクリップ、1 MB 超のクリップでの Decompress On Load、Master グループのリバーブ)に注意を促します。
評価を確認してもらってから、次に進みます。
3. リクエストを把握する
ユーザーの要望に応じて、該当するセクションに誘導します。
| ユーザーの発言 | パス |
|---|---|
| "audio memory too high" / "memory profiler shows audio" | セクション 4 — インポート設定の監査 |
| "load times slow" / "decompression stall" | セクション 4 — Load Type の確認 |
| "DSP spike" / "mixer CPU" / "audio CPU high" | セクション 4B — ミキサーの監査 |
| "3D sound wrong" / "only left channel plays" / "stereo in 3D" | セクション 4A — Force To Mono と空間設定 |
| "quality artifacts" / "voice sounds bad" / "Vorbis crackling" | セクション 4C — 圧縮品質の調整 |
| "mobile audio battery" / "mobile memory" | セクション 4D — モバイルのサンプルレートのオーバーライド |
| "set import settings on all clips" / "batch audio settings" | セクション 4 — インポート設定の一括監査 |
| "streaming" / "background loading" / "Addressables audio" | セクション 4E — ストリーミングと非同期読み込み |
症状が曖昧な場合は、「問題は音声メモリの使用量、DSP の CPU スパイク、音声再生の品質のどれですか?」と尋ねます。
4. 主な診断ワークフロー
セクション 2 の調査結果を使って、該当するサブセクションを判断します。複数の項目が同時に該当する場合もあります。
4A. Force To Mono と空間設定
spatialBlend > 0(3D 配置されたサウンド)の AudioSource について、次の手順に従います。
- クリップのチャンネル数を確認します:
evalを使用して、audioSource.clip.channelsを読み取ります。channels == 2かつspatialBlend == 1の場合、左チャンネルだけが再生されます。これは仕様ではなくバグです。 - Force To Mono を推奨します: resources/audio-import-api.md のインポーター読み取りレシピを使って現在の設定を確認し、Force To Mono を適用します。適用には Force To Mono のレシピを使用します。
- 適用して再インポートします: 適用前後のチャンネル数をユーザーに報告します。
- 空間ブレンドを検証します:
evalを使用して、audioSource.spatialBlendが1.0(完全な 3D)であり、audioSource.rolloffModeが適切なカーブに設定されていることを確認します。
4B. AudioMixer の監査
-
グループの階層の深さを測定します:
evalを使ってミキサーのグループツリーをたどり、階層数を数えます。3 階層を超える構造(Master → SFX / Music / Voice → サブバス)では、子グループが無音でも、フレームごとにルーティングのオーバーヘッドが発生します。 -
無音のグループにエフェクトが設定されていないか確認します:
evalを使って各グループのエフェクト一覧を取得します。AudioReverbFilterなどのエフェクトは、そのグループにルーティングされる AudioSource がなくても、DSP の処理を最大負荷で実行します。 -
親グループの SFX Reverb に注意します: これは組み込みエフェクトの中で最も負荷が高いものです。Master または上位グループで見つかった場合は、明示的に警告します。
-
推奨事項をユーザーに提示します:
- アクティブなソースがないグループのエフェクトを削除するか、バイパスします。
- 実行時にエフェクトを切り替えるのではなく、スナップショットを使ってミックスの状態(戦闘/探索/一時停止)を切り替えます。
- 不要なサブバスを統合し、ソースをより浅い階層の親グループにルーティングします。
ミキサーの変更を適用する前に、ユーザーの承認を待ちます。
-
DSP バッファーサイズを確認します: Pre-Flight の
bufferLengthが非常に小さい(< 256)場合は、増やすことを推奨します。resources/platform-settings.md の DSP Buffer Size Guidelines を参照してください。
4C. 圧縮品質の調整
- 現在の圧縮形式を読み取ります: resources/audio-import-api.md のインポーター設定を読み取るレシピを使い、ユーザーから報告されたクリップの
compressionFormatとqualityを読み取ります。 - プラットフォーム別の推奨設定を適用します: resources/platform-settings.md の Compression Format Matrix を参照してください。
- 非可逆圧縮のソースについて警告します: resources/audio-import-api.md の非可逆圧縮ソースの確認レシピを使います。元のファイルが MP3 の場合、Unity が再エンコードすると非可逆圧縮による品質劣化は永久に失われないことをユーザーに警告します。WAV または AIFF をソースとして使うことを推奨します。
4D. モバイルのサンプルレートオーバーライド
- モバイル向けの SFX クリップを特定します:
UnityEngine.AudioSourceのシーンコンポーネントクエリのレシピを使い、音楽とセリフ以外のクリップに絞り込みます。 - 現在のサンプルレート設定を読み取ります: resources/audio-import-api.md のインポーター設定を読み取るレシピを使い、各クリップの
sampleRateSettingとsampleRateOverrideを読み取ります。 - モバイル向けのオーバーライドを適用します: resources/audio-import-api.md のサンプルレートオーバーライドのレシピを使います。用途別のレートについては、resources/platform-settings.md の Sample Rate Recommendations を参照してください。
- 削減量を報告します: サンプルレートを半分にすると、PCM のメモリコストも半分になります。変更した各クリップについて、推定削減量を報告します。
4E. ロードタイプとストリーミング
- クリップごとにロードタイプを監査します:
evalを使い、セクション 2 で見つかった各クリップのclip.loadTypeを読み取ります。 - 判断ルールを適用します: Load Type Decision Table を resources/platform-settings.md で参照してください。
- 不一致に注意します: resources/platform-settings.md の Load Type Mismatch Flags を参照してください。2 種類の不一致をどちらもユーザーに報告します。
- Streaming クリップに
Load In Backgroundを適用します: resources/audio-import-api.md の Load In Background のレシピを使います。
5. 検証
インポート設定またはミキサーを変更した後は、次の手順を実行します。
- クリップの統計情報を再読み込みします:
evalを使ってclip.loadType、clip.channels、AudioSettings.outputSampleRate、およびインポーターのcompressionFormatを再度読み込み、再インポート後に変更が適用されたことを確認します。 - AudioSource のルーティングを確認します:
UnityEngine.AudioSourceのシーンコンポーネントクエリのレシピを使い、ミキサーの再構成後にaudioSource.outputAudioMixerGroupが想定どおりに割り当てられていることを確認します。 - 変更前後の差分を報告します: 変更した設定ごとに、変更前と変更後の値を示します。適用後のインポーターの値を読み取らずに、変更が有効になったと見なしてはいけません。
- 反復回数の上限: 調整と検証のサイクルは最大 3 回です。その後は一時停止し、ユーザーにフィードバックを求めます。
6. トラブルシューティング
3D AudioSource のステレオクリップで左チャンネルしか聞こえない
audioSource.spatialBlend == 1であることを確認します。audioSource.clip.channels == 2であることを確認します。- AudioClip インポーターで
forceToMonoを有効にして、再インポートします。Unity はインポート時に両方のチャンネルをモノラルにミックスし、normalize = true(有効のまま)で音量を維持します。 - ユーザーが再インポートを希望しない場合は、実行時の回避策として
audioSource.panStereo = 0を設定します。ただし、ステレオ情報は復元できないことを警告してください。
Decompress On Load のクリップでメモリ使用量が急増する
clip.loadType == AudioClipLoadType.DecompressOnLoadであり、clip.lengthが長い(5 秒超)ことを確認します。- 音楽や環境音の場合は
Streamingに、たまにしか再生しない場合はCompressedInMemoryに切り替えます。 - クリップが短いのにサイズが大きい場合は、
clip.channels(ステレオではメモリ使用量が 2 倍になります)とclip.frequency(モバイル向けターゲットでサンプルレートが高いとメモリを浪費します)を確認します。Force To Mono やサンプルレートのオーバーライドを適用します。
AudioMixer の CPU 使用率が急増する — DSP スレッドの負荷が高い
- ミキサーアセットのクエリ手順を使って、ミキサーグラフが存在することを確認します。
evalを使って、すべてのグループと、各グループにアタッチされたエフェクトを一覧表示します。上位グループにリバーブ、コーラス、イコライザーがないか確認します。- 負荷の高いエフェクトを、オーディオソースの再生中にのみアクティブになるリーフグループに移動します。
- メニュー表示中のリバーブを無効にするなど、聞こえないゲームプレイ状態ではスナップショットを使ってエフェクトチェーンをバイパスします。
- DSP バッファーが小さい(64 または 128 サンプル)場合は、サイズを大きくします。resources/platform-settings.md の「DSP Buffer Size Guidelines」を参照してください。
会話音声に Vorbis の音質劣化がある
defaultSampleSettings.compressionFormat == AudioCompressionFormat.Vorbisであることを確認します。defaultSampleSettings.qualityを確認します。デフォルトは 0.5 ですが、音声では劣化が聞こえることがよくあります。0.7〜0.85 に上げます。- iOS では、Vorbis ではなく AAC に切り替えます(ハードウェアデコードに対応し、同等のビットレートでより高音質です)。
- 元のファイルが可逆形式(WAV または AIFF)であることを確認します。MP3 のソースでは、Unity による再エンコード前に失われた音質を復元できません。
AudioListener の数が 1 ではない
- リスナーが 0 個の場合: すべてのオーディオが無音になります。
evalを使って、メインカメラにAudioListenerコンポーネントを追加します:UnityEngine.Camera.main.gameObject.AddComponent<UnityEngine.AudioListener>()。 - リスナーが複数ある場合: Unity は最後に有効化されたリスナーを使用するため、空間化の動作が予測できなくなります。
UnityEngine.AudioListenerのシーンコンポーネントのクエリ手順を使い、意図したもの以外をすべて無効にします。
Load In Background によって初回再生時に無音になる
これは想定どおりの動作です。最初に Play() を呼び出した時点で、クリップの読み込みが完了していません。次の方法で対処します。
- 必要になる前に
clip.LoadAudioData()を呼び出し、シーン開始時にクリップをプリロードします。 AudioSource.PlayScheduled()をわずかに遅らせて使い、非同期読み込みの完了を待ちます。- すぐに再生する必要がある AudioSource では、バックグラウンド読み込みを伴う
Streamingではなく、初回再生時に同期読み込みするCompressedInMemoryに切り替えます。
7. 完了
監査または最適化の完了後:
- 変更した設定をすべて、変更前と変更後の値とともに要約します。
- 引き続き対応が必要なクリップやグループを一覧表示します(例:削減効果の確認に実機での測定が必要なクリップ)。
- ユーザーが実行時のメモリ使用量を測定する必要がある場合は、実行時のバイトコストが大きい AudioClip を報告する Memory Profiler パッケージを案内します。
- 監査後もミキサーの CPU 使用率が高い場合は、DSP スレッドのプロファイリングに Unity Profiler の Audio モジュールを案内します。
詳細リファレンス
- プラットフォーム設定、圧縮マトリックス、読み込みタイプ、サンプルレート: resources/platform-settings.md
- AudioImporter API の手順とコードパターン: resources/audio-import-api.md
関連項目
- Memory Profiler package — 実行時のバイトコストが最も大きい AudioClips を見つけます。
- Unity Profiler, Audio module — DSP の CPU マーカーとフレーム時間の予算を確認します。
audio-setup-mixers— ミキサーを作成し、Audio Sources をグループにルーティングします。