mcpField
U
unity-audio

unity-audio

github.com/nice-wolf-studio開発4069 回インストール6 週間前に更新
リポジトリ

unity-audio について

Unity のオーディオシステムを扱う開発者向けのリファレンススキルです。ソース、リスナー、ミキサー、空間オーディオの設定とスクリプト例に加え、インポートや再生、リソース管理の注意点をまとめています。

主な機能

  1. 01AudioSource と AudioListener の解説
  2. 02Audio Mixer、エフェクト、スナップショットの設定
  3. 033D 空間オーディオと減衰の設定
  4. 04音声形式、読み込み、圧縮の説明
  5. 05再生、フェード、オーディオプールのパターン
  6. 06よくあるアンチパターンの紹介

活用シーン

  1. 01シーン内オブジェクトの 3D サウンドを設定
  2. 02音楽や効果音のミキシングと音量を管理
  3. 03長い音声の読み込みと圧縮方式を選択
  4. 04再生の重なりやリソース使用の問題を回避

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-audio

インストール後、Claude Code で/unity-audioを入力して読み込まれたか確認します。

同梱ファイルreferences/audio-api.md

詳細

Unity オーディオシステム

オーディオシステムの概要

Unity のオーディオシステムは、完全な 3D 空間サウンド、リアルタイムのミキシングとマスタリング、ミキサーの階層、スナップショット、定義済みのエフェクトを提供します。中核となるアーキテクチャは、ソースとリスナーのモデルに従っています。

  1. AudioClip -- プロジェクトにインポートされたオーディオデータのコンテナー
  2. AudioSource -- AudioClip を再生する、GameObject にアタッチされたコンポーネント
  3. AudioListener -- ソースから音声を受信してスピーカーに出力する、マイクのようなコンポーネント(通常は Main Camera に配置)
  4. Audio Mixer -- ソースのミキシング、エフェクトの適用、出力のマスタリングを行う中心的なハブ

オブジェクトにアタッチされた AudioSource からサウンドが発生し、AudioListener が受け取ります。Unity はリスナーからのソースの距離と位置を計算し、音量、パン、3D エフェクトを決定します。また、ソースオブジェクトとリスナーオブジェクトの相対速度を使ってドップラー効果もモデル化します。

対応オーディオ形式
形式種類
.aif、.wav非圧縮
.mp3、.ogg圧縮
.xm、.mod、.it、.s3mトラッカーモジュール

Unity はモノラル、ステレオ、マルチチャンネルのオーディオアセット(最大 8 チャンネル)に対応しています。


AudioSource と AudioListener

AudioSource

AudioSource コンポーネントはシーン内で AudioClip を再生し、再生動作をカスタマイズするオプションを提供します。主なプロパティは次のとおりです。

プロパティ説明デフォルト
clip再生する AudioClipなし
volume再生音量(0.0~1.0)1.0
pitch再生速度/ピッチの倍率1.0
loopクリップの再生完了後にループするかどうかfalse
playOnAwakeGameObject のアクティブ化時に自動再生するかどうかtrue
spatialBlend2D(0.0)から 3D(1.0)へのブレンド0.0
priorityソースの優先度(0 = 最高、256 = 最低)128
mute再生を停止せずにソースをミュートfalse
outputAudioMixerGroupルーティング先のミキサーグループなし
3D サウンド設定
プロパティ説明
dopplerLevelドップラー効果の強度スケール
spread3D ステレオ/マルチチャンネルの広がり角度(度)
rolloffMode距離に応じた音量の減衰方法(Logarithmic、Linear、Custom)
minDistance音量が最大になる距離
maxDistance音が聞こえなくなる、または減衰が止まる距離
panStereoステレオパンの位置(-1 が左、1 が右)
reverbZoneMixグローバルリバーブへのミックスレベル
AudioListener

AudioListener はマイクのようなデバイスとして機能し、シーン内の AudioSource からの入力を受信してスピーカーから出力します。重要なルールは次のとおりです。

  • シーンごとに AudioListener は 1 つだけ -- これは厳守が必要な制約です
  • デフォルトでは Main Camera に追加されます
  • Inspector で設定できるプロパティはありません -- 動作させるには追加するだけです
  • 3D の位置オーディオと 2D オーディオ(3D 処理を無視)をどちらも処理します
  • 聞こえるすべてのサウンドに Reverb Zones と Audio Effects を適用します

スクリプトから使用できる静的プロパティ:

  • AudioListener.volume -- マスター音量(0.0~1.0)
  • AudioListener.pause -- オーディオシステム全体を一時停止/再開

AudioClip とインポート設定

読み込みタイプ
読み込みタイプ動作最適な用途
Decompress On Load読み込み時にすぐに解凍します。Vorbis では約 10 倍、ADPCM では約 3.5 倍のメモリを使用します小さく、頻繁に使用する効果音
Compressed In Memoryメモリ内では圧縮状態を保ち、再生中に解凍します。CPU の負荷がわずかに増加します読み込み時の解凍ではメモリ予算を超える、中程度の長さのサウンド
Streamingディスクからリアルタイムでデコードします。クリップごとに約 200KB のバッファーを使用します音楽や環境音トラックなどの長いオーディオ
圧縮形式
形式圧縮率最適な用途
PCM1:1(非圧縮)デコード時の CPU コストがかからない、ごく短い効果音
ADPCM3.5:1ノイズの多いサウンド(足音、衝撃音、武器音)
Vorbis/MP3可変(品質スライダー)音楽や中程度の長さの効果音
インポート設定
設定説明
Force To Monoパッキング前にマルチチャンネルオーディオをモノラルトラックにミックスダウンします
Normalizeモノラル変換中にオーディオをノーマライズします
Load In Backgroundメインスレッドをブロックしないよう、クリップを非同期で読み込みます
Ambisonicファイルに Ambisonic エンコードされた音場が含まれることを示します(XR/360 向け)
Preload Audio Dataシーンの読み込み完了時にクリップデータを事前読み込みします(デフォルト:有効)
QualityVorbis/MP3 形式の圧縮品質スライダー
Sample Rate SettingPreserve、Optimize(自動調整)、または Override(手動で低減)

オーディオミキサー

オーディオミキサーは、オーディオ出力のミキシング、エフェクト処理、マスタリングを行います。すべてのオーディオミキサーアセットには、デフォルトで Master Group が含まれます。

基本概念
  • グループ(バス) -- 音量減衰とピッチ補正を制御する信号チェーンで、階層的に構成されます(例:Master/SFX/Weapons)
  • スナップショット -- 実行時に切り替えて異なるムードや雰囲気を作り出せる、保存済みのパラメーター設定
  • エフェクト -- グループの信号チェーン内で適用される DSP エフェクト(リバーブ、エコー、EQ など)
  • センド/リターン -- あるバスの結果を別のバスに渡し、エフェクト処理を共有します
  • ダッキング -- 別のグループの動作に応じて、あるグループの出力を変更します(例:会話の再生中に環境音を小さくする)
  • ビュー -- 複雑なミキサーレイアウトを管理するための、さまざまな表示設定
  • 公開パラメーター -- SetFloat/GetFloat を介したスクリプト制御に公開されるミキサーパラメーター

注記: Web プラットフォームでは、オーディオミキサーは部分的にしかサポートされていません。

ミキサーのスクリプト制御
using UnityEngine;
using UnityEngine.Audio;

public class MixerController : MonoBehaviour
{
    [SerializeField] private AudioMixer mixer;

    // Set exposed parameter (must be exposed in the Mixer Inspector)
    public void SetVolume(float linear)
    {
        float dB = Mathf.Log10(Mathf.Max(linear, 0.0001f)) * 20f;
        mixer.SetFloat("MasterVolume", dB);
    }

    // Read exposed parameter (convert dB back to linear)
    public float GetVolume()
    {
        if (mixer.GetFloat("MasterVolume", out float dB))
            return Mathf.Pow(10f, dB / 20f);
        return 1f;
    }

    // Reset parameter to snapshot-defined value
    public void ResetVolume() => mixer.ClearFloat("MasterVolume");

    // Transition to a named snapshot
    public void GoToSnapshot(string name, float time)
    {
        var snap = mixer.FindSnapshot(name);
        if (snap != null) snap.TransitionTo(time);
    }

    // Blend multiple snapshots with weights
    public void BlendSnapshots(AudioMixerSnapshot[] snaps, float[] weights, float time)
        => mixer.TransitionToSnapshots(snaps, weights, time);
}

3D 空間オーディオ

基本的な 3D サウンドの設定

完全な 3D 位置指定を行うには、spatialBlend を 1.0 に設定します。Unity の組み込みパンニングは、リスナーからの距離と角度に基づいて、左右の耳への音の寄与を調整します。

空間化プラグイン(HRTF)

高度な 3D オーディオ向けに、Unity は HRTF フィルタリングを備えた空間化プラグインをサポートしています。設定方法:(1) Edit > Project Settings > Audio で空間化プラグインを選択し、(2) 各 AudioSource で Spatialize を有効にし、(3) 必要に応じて spatializePostEffects を設定します。パフォーマンスのヒント:近くのサウンドのみを空間化し、遠くのサウンドには従来のパンニングを使用します。

減衰モード
  • Logarithmic -- 現実的な減衰:近距離では大きく、急速に減衰します(デフォルト)
  • Linear -- minDistance と maxDistance の間で一定の減衰を行います
  • Custom -- ユーザー定義の AnimationCurve
using UnityEngine;

public class SpatialAudioSetup : MonoBehaviour
{
    [SerializeField] private AudioSource audioSource;

    void Start()
    {
        // Configure for 3D spatial audio
        audioSource.spatialBlend = 1.0f;       // Full 3D
        audioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        audioSource.minDistance = 1f;
        audioSource.maxDistance = 50f;
        audioSource.dopplerLevel = 1.0f;
        audioSource.spread = 0f;               // Point source

        // Enable spatialization plugin (if configured in Project Settings)
        audioSource.spatialize = true;
    }
}

よく使われるパターン

効果音の再生
using UnityEngine;

public class SoundEffectPlayer : MonoBehaviour
{
    [SerializeField] private AudioSource audioSource;
    [SerializeField] private AudioClip shootClip;
    [SerializeField] private AudioClip reloadClip;

    // Play the assigned clip
    public void PlayShoot()
    {
        audioSource.Play();
    }

    // PlayOneShot: plays a clip without interrupting the current one
    // Supports overlapping sounds and per-call volume scaling
    public void PlayReload(float volumeScale = 1.0f)
    {
        audioSource.PlayOneShot(reloadClip, volumeScale);
    }

    // Play a clip at a world position (creates a temporary AudioSource)
    public void PlayExplosionAt(Vector3 position)
    {
        AudioSource.PlayClipAtPoint(shootClip, position, 1.0f);
    }

    // Play with a delay (in seconds)
    public void PlayDelayed()
    {
        audioSource.PlayDelayed(0.5f);
    }

    // Scheduled playback on DSP timeline (sample-accurate)
    public void PlayScheduled()
    {
        double startTime = AudioSettings.dspTime + 1.0;
        audioSource.PlayScheduled(startTime);
    }
}
オーディオオブジェクトのプーリング
using UnityEngine;
using System.Collections.Generic;

public class AudioPool : MonoBehaviour
{
    [SerializeField] private int poolSize = 10;
    private List<AudioSource> pool = new List<AudioSource>();

    void Awake()
    {
        for (int i = 0; i < poolSize; i++)
        {
            var obj = new GameObject($"PooledAudio_{i}");
            obj.transform.SetParent(transform);
            var src = obj.AddComponent<AudioSource>();
            src.playOnAwake = false;
            pool.Add(src);
        }
    }

    public AudioSource Play(AudioClip clip, Vector3 pos, float volume = 1f)
    {
        var source = pool.Find(s => !s.isPlaying);
        if (source == null) return null;
        source.transform.position = pos;
        source.clip = clip;
        source.volume = volume;
        source.Play();
        return source;
    }
}
コルーチンによるオーディオのフェード
using UnityEngine;
using System.Collections;

public class AudioFader : MonoBehaviour
{
    [SerializeField] private AudioSource musicSource;

    public void CrossFadeTo(AudioClip newClip, float duration)
    {
        StartCoroutine(CrossFadeCoroutine(newClip, duration));
    }

    private IEnumerator CrossFadeCoroutine(AudioClip newClip, float duration)
    {
        float startVol = musicSource.volume;
        float half = duration / 2f;

        // Fade out
        for (float t = 0f; t < half; t += Time.deltaTime)
        { musicSource.volume = Mathf.Lerp(startVol, 0f, t / half); yield return null; }

        // Switch clip and fade in
        musicSource.clip = newClip;
        musicSource.Play();
        for (float t = 0f; t < half; t += Time.deltaTime)
        { musicSource.volume = Mathf.Lerp(0f, startVol, t / half); yield return null; }

        musicSource.volume = startVol;
    }
}
UI スライダーによるミキサー音量の制御
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

public class VolumeSettings : MonoBehaviour
{
    [SerializeField] private AudioMixer mixer;
    [SerializeField] private Slider masterSlider;

    void Start()
    {
        masterSlider.value = PlayerPrefs.GetFloat("MasterVol", 1f);
        masterSlider.onValueChanged.AddListener(v => SetVolume("MasterVol", v));
    }

    // Exposed parameter names must match those set in the Audio Mixer Inspector
    private void SetVolume(string param, float linear)
    {
        float dB = linear > 0.0001f ? Mathf.Log10(linear) * 20f : -80f;
        mixer.SetFloat(param, dB);
        PlayerPrefs.SetFloat(param, linear);
    }
}
オーディオの一時停止と再開
// Pause all audio globally
AudioListener.pause = true;

// UI sounds can bypass the global pause
uiSource.ignoreListenerPause = true;

// Resume all audio
AudioListener.pause = false;

// Pause/resume a single source (remembers playback position)
musicSource.Pause();
musicSource.UnPause();

アンチパターン

1. シーン内に複数の AudioListener を配置する

シーン内に存在できる AudioListener は 1 つだけです。副カメラから AudioListener を削除するか、カメラの切り替え時に有効/無効を切り替えてください。

2. 重ねて再生する効果音に Play() を使う
// BAD: Play() restarts the clip, cutting off the previous playback
void OnShoot()
{
    audioSource.clip = gunshot;
    audioSource.Play(); // Interrupts previous gunshot
}

// GOOD: PlayOneShot allows overlapping instances
void OnShoot()
{
    audioSource.PlayOneShot(gunshot, 0.8f);
}
3. 線形値でミキサー音量を設定する
// BAD: Mixer parameters use decibels, not linear 0-1
mixer.SetFloat("MasterVol", 0.5f); // Almost silent, not half volume

// GOOD: Convert linear to logarithmic decibels
float dB = Mathf.Log10(Mathf.Max(value, 0.0001f)) * 20f;
mixer.SetFloat("MasterVol", dB);
4. すべてのオーディオを Decompress On Load で読み込む

大きなオーディオファイル(音楽、会話)を Decompress On Load に設定すると、大量のメモリを消費します(Vorbis では約 10 倍)。長いクリップには Streaming、中程度の長さのクリップには Compressed In Memory を使用してください。

5. 3D サウンドの spatialBlend を設定し忘れる
// BAD: spatialBlend defaults to 0 (2D) -- sound ignores 3D position
AudioSource source = gameObject.AddComponent<AudioSource>();
source.clip = explosionClip;
source.Play(); // Plays at full volume regardless of distance

// GOOD: Set spatialBlend to 1 for 3D positioning
source.spatialBlend = 1.0f;
source.minDistance = 1f;
source.maxDistance = 50f;
source.Play();
6. 頻繁に再生する効果音に PlayClipAtPoint を使う

PlayClipAtPoint は呼び出すたびに一時的な GameObject を作成し、破棄します。銃声や足音など、頻繁に再生するサウンドには、代わりにオーディオプールを使用してください。

7. 3D 効果音で「Force To Mono」を使用しない

3D ソースとして使用するステレオファイルはメモリを無駄に消費します。3D 空間化の際にステレオチャンネルはモノラルに統合されます。3D 効果音では、インポート設定で Force To Mono を有効にしてください。


主要 API クイックリファレンス

API説明備考
AudioSource.Play()割り当てられたクリップを再生します再生中の場合は最初から再生します
AudioSource.PlayOneShot(clip, vol)現在の再生を中断せずにクリップを再生します重ねて再生できます
AudioSource.PlayClipAtPoint(clip, pos)静的メソッド:ワールド座標で再生します一時的な GameObject を作成します
AudioSource.PlayDelayed(delay)秒単位の遅延後に再生します
AudioSource.PlayScheduled(time)DSP 時刻に再生しますサンプル単位で正確にスケジュールできます
AudioSource.Stop()再生を停止します
AudioSource.Pause()再生を一時停止します再生位置を記憶します
AudioSource.UnPause()一時停止した再生を再開します
AudioSource.isPlayingソースが現在再生中かどうかを示します読み取り専用
AudioSource.time秒単位の再生位置です読み書き可能
AudioSource.timeSamplesPCM サンプル単位の再生位置です読み書き可能
AudioListener.volume全体のマスターボリュームです静的、0.0-1.0
AudioListener.pauseすべてのオーディオを一時停止します静的 bool
AudioClip.length秒単位のクリップの長さです読み取り専用
AudioClip.samplesサンプル単位のクリップの長さです読み取り専用
AudioClip.channelsオーディオチャンネル数です読み取り専用
AudioClip.frequencyHz 単位のサンプルレートです読み取り専用
AudioClip.loadState現在の読み込み状態です読み取り専用
AudioClip.Create(name, len, ch, freq, stream)実行時に AudioClip を作成します
AudioClip.GetData(data, offset)サンプルデータを配列に読み込みます
AudioClip.SetData(data, offset)配列のサンプルデータを書き込みます
AudioClip.LoadAudioData()クリップデータをメモリに読み込みます
AudioClip.UnloadAudioData()クリップデータをメモリからアンロードします
AudioMixer.SetFloat(name, val)公開パラメーターを設定します見つからない場合は false を返します
AudioMixer.GetFloat(name, out val)公開パラメーターの値を取得します見つからない場合は false を返します
AudioMixer.ClearFloat(name)パラメーターをスナップショットの値にリセットします
AudioMixer.FindSnapshot(name)名前が完全一致するスナップショットを検索しますAudioMixerSnapshot を返します
AudioMixer.FindMatchingGroups(path)パスパターンでグループを検索しますAudioMixerGroup[] を返します
AudioMixer.TransitionToSnapshots(snaps, weights, time)重み付けしてスナップショットをブレンドします
AudioMixerSnapshot.TransitionTo(time)このスナップショットに遷移します

関連スキル

  • unity-foundations -- GameObject、コンポーネント、Transform、Prefab、ScriptableObject
  • unity-scripting -- C# スクリプトのパターン、MonoBehaviour のライフサイクル、コルーチン、イベント
  • unity-animation -- Animator Controller、Timeline、アニメーションイベント(オーディオとアニメーションの同期に便利です)

追加リソース

コメント