[Unity] オーディオ再生、ダッキング再生、フェードイン再生について覚えた事まとめ

Unityには音を再生する機能が備わっています。備わっていますがどうやって使ってよいか戸惑うところです。なので自分なりの使用結果をメモしておきます。

基本的な使い方や、自分が使うであろう機能だけを学習したので相当な抜けがあると思いますが、とっかかりとして参考になれば。

 

 

 

環境

Unity 5.0

 

参考サイト

第08回 音をつける

その1 Unityのサウンドの根っこ

[Unity] Unityで音を再生する

ぼくがかんがえたさいきょうのAudioManager2【Unity】

【Unity】とっても簡単に扱えるBGM再生クラスを作ってみた。フェードイン、フェードアウト対応版

AudioMixer and AudioMixer Groups(公式チュートリアル)

Unity のオーディオの再生・エフェクト・解析周りについてまとめてみた(凹みTips)

 

コンポーネントメモ

基本的なオーディオ関係のコンポーネントは4つあります。

AudioClip → 音データ

AudioSource → スピーカー

AudioListener → 耳 (シーン内に1つしか存在できない。通常はCameraに付いている。)

AudioMixer → 音の調整

これだけ覚えておけば混乱しないはず。

 

ミキサーを準備し、各グループを準備する

AudioMixerを新規作成します。ミキサーをダブルクリックかAudio Mixerビューを表示します。最初にあるこのAudioGroupをマスター音量とします。

Bgm、SE、Voiceの3つのグループを作成します。

audiomixer_add_group

グループは親子関係を持つことができるのですが、ここではすべてMasterの子グループとして追加しました。

 

AudioSourceコンポーネントを準備

空のGameObjectにAudioSourceコンポーネントを追加し、AudioClipプロパティに再生したい音を指定しておきます。

次に出力先のミキサーグループを指定します。Bgm用ならBgmグループを指定し、音声ならVoiceグループを指定します。グループ別に音量変更やエフェクト追加が出来るので管理が簡単になりそうです。

audiomixer_initial_source

他の設定はお好みで。BgmならLoopはONにしたり。

 

Voiceグループはダッキング再生を行う

ダッキングとは「音声再生時に他の音量(例えばBGM)を絞る事」を指します。音量を絞る対象=BgmグループにDuck Volumeエフェクトを追加します。ちなみにAudio MixerのリファレンスのEffect一覧にはDuck Volumeエフェクトは載っていません。Audio Overviewには載ってたのですが・・・。

ダッキングするのはBgmなのでBgmグループに「Duck Volume」を追加します。

audiomixer_add_duckvolume

そしてVoiceグループには「Send」を追加し、Receiveには「Bgm/Duck Volume」を選択。Send levelを0.00dBにします。

audiomixer_add_send

Duck Volumeエフェクトのパラメーターを調整しましょう。パラメーターの意味は後回しにしてThresholdを-40.00dBに変更。

audiomixer_param_duckvolume

上記設定を行った上でテストしてみてください。Voiceグループの音声再生時に、Bgmグループの音量が下がっているはずです。

 

フェードイン、フェードアウトを行うには?

標準で存在しないっぽいのでスクリプトで行う必要がありそうです。AudioManagerとAudioPlayerというクラスを作成して、フェードイン再生、フェードアウト再生に対応します。

 

AudioManagerを作成

シングルトン、かつ全シーンで使用できるように実装します。このマネージャーでは再生中の情報を管理することにします。

Unityでは3D空間の位置によって聞こえる音が変化するように作られているので、AudioSource(スピーカー)を付ける先は音を発生させるGameObjectになります。このマネージャーでは直接管理しないほうが良いでしょう。

グループ別に再生中のAudioPlayer(下記クラス)を取得できるようにしておきます。

using UnityEngine;
using UnityEngine.Audio;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// オーディオ情報を管理します。
/// </summary>
public class AudioManager : SingletonMonoBehaviour<AudioManager>
{
  /// <summary>
  /// 使用するオーディオミキサー。
  /// </summary>
  public AudioMixer Mixer;

  /// <summary>
  /// 使用するオーディオグループ。
  /// </summary>
  public AudioMixerGroup MixerBgmGroup;
  public AudioMixerGroup MixerSeGroup;
  public AudioMixerGroup MixerVoiceGroup;

  /// <summary>
  /// 管理しているオーディオ情報
  /// </summary>
  public List<AudioPlayer> AudioPlayers { get; private set; }

  /// <summary>
  /// 管理しているBgm情報を取得します。
  /// </summary>
  public List<AudioPlayer> AudioBgmPlayers
  {
    get { return AudioPlayers.FindAll(ap => ap.Source.outputAudioMixerGroup == MixerBgmGroup); }
  }

  /// <summary>
  /// 管理しているSe情報を取得します。
  /// </summary>
  public List<AudioPlayer> AudioSePlayers
  {
    get { return AudioPlayers.FindAll(ap => ap.Source.outputAudioMixerGroup == MixerSeGroup); }
  }

  /// <summary>
  /// 管理しているVoice情報を取得します。
  /// </summary>
  public List<AudioPlayer> AudioVoicePlayers
  {
    get { return AudioPlayers.FindAll(ap => ap.Source.outputAudioMixerGroup == MixerVoiceGroup); }
  }

  /// <summary>
  /// コンストラクタ
  /// </summary>
  public AudioManager()
  {
    AudioPlayers = new List<AudioPlayer>();
  }
  
  /// <summary>
  /// 起動時の初期化処理を行います。
  /// </summary>
  void Awake()
  {
    if( this != Instance ) {
      // 既に存在しているなら削除
      Destroy(gameObject);
    }
    else {
      // 音管理はシーン遷移では破棄させない
      DontDestroyOnLoad(this.gameObject);
    }
  }

  /// <summary>
  /// プレイヤーの登録を行います。
  /// </summary>
  /// <param name="player"></param>
  public void RegistPlayer( AudioPlayer player )
  {
    AudioPlayers.Add(player);
  }

  /// <summary>
  /// プレイヤーの登録解除を行います。
  /// </summary>
  /// <param name="player"></param>
  public void UnregistPlayer( AudioPlayer player )
  {
    AudioPlayers.Remove(player);
  }
}

 

AudioSourceを持つAudioPlayerを作成

基本的なメソッドは再生、停止、フェードアウト停止、一時停止です。実行時にはAudioManagerへの登録、解除を内部的に行います。

「Bgmはシーン内で1つのみ再生できる」というルールを追加したいので、このクラスの再生メソッド内で他のBgmを停止しています。(本来AudioManagerが行うのでしょうが・・・)

using UnityEngine;
using System.Collections;

public class AudioPlayer : MonoBehaviour 
{
  /// <summary>
  /// オーディオソース。
  /// </summary>
  public AudioSource Source;

  /// <summary>
  /// フェードイン再生を行うかどうか。
  /// </summary>
  public bool IsFade;

  /// <summary>
  /// フェードインする時の時間。
  /// </summary>
  public double FadeInSeconds = 1.0;

  /// <summary>
  /// フェードイン再生中かどうか
  /// </summary>
  bool IsFadePlaying = false;

  /// <summary>
  /// フェードアウト再生中かどうか
  /// </summary>
  bool IsFadeStopping = false;

  /// <summary>
  /// フェードアウトする時の時間。
  /// </summary>
  double FadeOutSeconds = 1.0;

  /// <summary>
  /// フェードイン/アウト経過時間。
  /// </summary>
  double FadeDeltaTime = 0;

  /// <summary>
  /// 基本ボリューム。
  /// </summary>
  float BaseVolume;
 
  /// <summary>
  /// 
  /// </summary>
  public void OnEnable()
  {
    AudioManager.Instance.RegistPlayer(this);
  }

  /// <summary>
  /// 
  /// </summary>
  public void OnDisable()
  {
    Source.Stop();
    AudioManager.Instance.UnregistPlayer(this);
  }

  /// <summary>
  /// フレーム毎処理。
  /// </summary>
  void Update()
  {
    // フェードイン
    if( IsFadePlaying ) {
      FadeDeltaTime += Time.deltaTime;
      if( FadeDeltaTime >= FadeInSeconds ) {
        FadeDeltaTime = FadeInSeconds;
        IsFadePlaying = false;
      }
      Source.volume = (float)(FadeDeltaTime / FadeInSeconds) * BaseVolume;
    }

    // フェードアウト
    if( IsFadeStopping ) {
      FadeDeltaTime += Time.deltaTime;
      if( FadeDeltaTime >= FadeOutSeconds ) {
        FadeDeltaTime = FadeOutSeconds;
        IsFadePlaying = false;
        Source.Stop();
      }
      Source.volume = (float)(1.0 - FadeDeltaTime / FadeOutSeconds) * BaseVolume;
    }
  }

  /// <summary>
  /// 再生を行います。
  /// </summary>
  public void Play()
  {
    // 自分がBgmの場合には、他のBgmの再生を停止させます。
    var bgm = AudioManager.Instance.AudioBgmPlayers;
    if( bgm.Contains(this) ) {
      foreach( var player in bgm ) {
        if( player == this ) { continue; }

        if( player.Source.isPlaying ) {
          if( IsFade ) {
            player.StopFadeOut(FadeInSeconds);
          }
          else {
            player.Stop();
          }
        }
      }
    }

    BaseVolume = 1;
    FadeDeltaTime = 0;
    Source.volume = 0;
    Source.Play();
    IsFadePlaying = true;
    IsFadeStopping = false;
  }

  /// <summary>
  /// 停止を行います。
  /// </summary>
  public void Stop()
  {
    Source.Stop();
  }

  /// <summary>
  /// 停止を行います。
  /// <param name="fadeSec">フェードアウト完了までの秒数。</param>
  /// </summary>
  public void StopFadeOut( double fadeSec )
  {
    BaseVolume = Source.volume;
    FadeDeltaTime = 0;
    FadeOutSeconds = fadeSec;
    IsFadeStopping = true;
    IsFadePlaying = false;
  }

  /// <summary>
  /// 一時停止を行います。
  /// </summary>
  public void Pause()
  {
    Source.Pause();
  }
}

AudioSourceとAudioPlayerはこんな感じで使えばよいはず。

audiomixer_set_player

 

マスターボリュームの調整方法

AudioListener.volumeプロパティで行えます。3D Soundでも2D Soundでも大丈夫。

AudioMixerを使用しているならAudioMixer側でも調整可能。

 

デモ

BGMは4秒かけてフェードイン/アウトして切り替わります。効果音(ボイス)はダッキング再生されます。

BGMは下側で操作。効果音(ボイス)は上側のボタンで再生。音が出るので注意。

BGM : 魔王魂

音声 : ユニティちゃん スーパー売り子ボイスパック

 

ユニティちゃんライセンス

ユニティちゃんライセンス
このコンテンツは、『ユニティちゃんライセンス』で提供されています


希木小鳥

Diablo1でハクスラの世界に。今はBorderlands2をプレイ中。ぬるゲーマー。

あわせて読みたい