5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unityでシーン切り替えを気にせずBGMを再生させ続ける方法

Last updated at Posted at 2016-08-20

前書き

Unityでゲームの作成時、シーンによっていちいちAudioSourceを作成したりしなければならなかったのが面倒くさかったので作成した。
名前を仮に「SoundController」とする。

SoundControllerを利用することで得られるメリット

・シーン切り替え時などにいちいちBGMを切り替えるスクリプトを書かなくてよい
・フェードも自動
・最初のシーンでサウンドデータを読み込んでいるので、シーン切り替え時間がだいぶ短縮できる。

とかくインスペクタだけでほぼ作業完了できるので面倒がだいぶ省けます。

使い方

・一番最初に読み込まれるシーンを開きます。
・空のゲームオブジェクトを作成し、SoundControllerを貼り付けます。
・sourceにAudioSourceを設定します。(このオブジェクト以外のものを設定した場合、シーン切り替え時に破棄されてしまいます。なので3D音声にこだわらないのであればAudioSourceはこのオブジェクトに設定するのを推奨)
・BGMリストに「シーン名:AudioClip」の組み合わせでデータを登録します。

 
以下ソース。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using System.Linq;
using System;

public class SoundController : MonoBehaviour {
    
    /// <summary>
    /// 使用するBGMリスト
    /// </summary>
    public List<BGMSelectItem> BGMList = new List<BGMSelectItem>();
    /// <summary>
    /// オーディオソース。
    /// </summary>
    public AudioSource source;
    /// <summary>
    /// BGMの設定ボリューム。自動的にこの値までフェードする
    /// </summary>
    public float MasterVolume = 0.5f;

    /// <summary>
    /// シーンごとのBGMを取得する
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    private AudioClip this[string s]
    {
        get
        {
            return BGMList
                .Where(a => a.key == s)
                .Select(b=>b.clip)
                .FirstOrDefault();
        }
    }

    void Awake()
    {        
        DontDestroyOnLoad(this);
    }
    /// <summary>
    /// シーン切り替え時に呼ばれる。BGMをここで切り替える
    /// </summary>
    /// <param name="level"></param>
    /// <returns></returns>
    IEnumerator OnLevelWasLoaded(int level)
    {
        //フェードアウト
        while (Fade(-0.2f*0.1f))
        {
            yield return new WaitForSeconds(0.1f);
        }
        yield return new WaitForSeconds(1);
        source.clip = this[SceneManager.GetActiveScene().name];            
        source.Play(1);
        while (Fade(+0.2f * 0.1f))
        {
            yield return new WaitForSeconds(0.1f);
        }

        yield break;
    }

    /// <summary>
    /// 自動的にマスタボリュームまでフェードイン/フェードアウトする
    /// </summary>
    /// <param name="gain"></param>
    /// <returns></returns>
    private bool Fade(float gain)
    {
        if (this.source.volume + gain <= 0 || this.MasterVolume <= this.source.volume +gain)
        {
            return false;
        }

        this.source.volume += gain;
        return true;
    }

}

[Serializable]
public struct BGMSelectItem
{
    public string key;
    public AudioClip clip;
}


注意

最初のシーンではフェードが利きません。
なので、AudioSourceの最初のVolumeはあらかじめ再生しておきたい音量に手動で設定してください。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?