【学習】Unity 6:シーンが切り替わっても BGM を止めない(DontDestroyOnLoad とシングルトン)
Unity でゲーム制作をしていると、タイトル画面・ゲーム画面・リザルト画面など、複数シーンを切り替える構成が一般的になります。
そのとき多いのが次の問題です。
- シーンが切り替わるたびに BGM が止まる
今回は、シーンをまたいでも BGM を流し続ける考え方と、Unity 6 での Inspector の違いまで、ひと通り整理します。
今日のゴール
- なぜシーン切替で BGM が止まるか説明できる
DontDestroyOnLoadと シングルトン(1 個だけ残す) で BGM マネージャーを実装できる- Unity 6 の Audio Source まわりの表示の変化を混乱なく扱える
なぜ BGM が止まるのか
Unity では、シーンをロードし直すとそのシーンに属していた GameObject は破棄されるのが基本です。
例えば次のような構成だとします。
TitleSceneBGMManager(AudioSource付き)
ここから GameScene に SceneManager.LoadScene などで移ると、TitleScene 側の BGMManager も一緒に消えるため、AudioSource の再生も止まります。
つまり問題の本質は「音だけ」ではなく、シーンに置いたオブジェクトはシーンとセットで寿命が切れるという Unity のルールです。
解決の考え方:DontDestroyOnLoad
Unity には、ロード専用の隠しシーンへオブジェクトを退避し、次のシーン読み込み後も破棄しないための API があります。
DontDestroyOnLoad(gameObject);これで、その GameObject(と子オブジェクト)はシーン切替後も残り、BGM の再生を継続できます。
注意点として、同じマネージャーを各シーンに置き続けると、退避したオブジェクトに加えて新しいオブジェクトも生き残り、二重再生になりがちです。そこでよく組み合わせるのが シングルトン(インスタンスは常に 1 つ)です。
完成コード
同じ GameObject に AudioSource とこのスクリプトを付けます。
using UnityEngine;
public class BGMManager : MonoBehaviour
{
private static BGMManager instance;
[SerializeField]
private AudioClip bgmClip;
private AudioSource audioSource;
private void Awake()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
audioSource = GetComponent<AudioSource>();
audioSource.clip = bgmClip;
audioSource.loop = true;
audioSource.Play();
}
}GameObject の準備(Hierarchy)
- 空の
GameObjectを作成し、名前例:BGMManager - 次のコンポーネントを追加する
AudioSourceBGMManager(上記スクリプト)
AudioSource の Inspector 設定(目安)
| 項目 | 設定 |
|---|---|
| Play On Awake | 状況に合わせて調整(下記参照) |
| Loop | ON(コードでも loop = true を入れています) |
| Audio Resource / Clip | 使う BGM ファイル |
補足(上級者向けの整理)
このサンプルでは Awake() で Play() しています。実行順によっては Play On Awake が ON だと二重に再生が走ることがあるため、Awake で制御するなら Play On Awake は OFF にそろえると安全、という運用もよく使われます(教材によっては ON のままにしていることもあります)。
コード解説
BGMManager を 1 つだけにする
private static BGMManager instance;static なフィールドはシーンではなく型に紐づく共有領域のイメージです。
「現在の正」として、生き残るインスタンスを 1 つだけ保持します。
重複生成を防ぐ
if (instance != null)
{
Destroy(gameObject);
return;
}各シーンに BGMManager を置く運用でも、先に存在していた方を正として、後から出現した方を破棄します。
これで BGM の二重再生を防ぎます。
シーン切替でも消さない(最重要)
DontDestroyOnLoad(gameObject);ここが今回の要です。通常ならシーンと一緒に消えるオブジェクトを、ロード後も残す側へ移します。
AudioSource を取得して設定し、再生する
audioSource = GetComponent<AudioSource>();
audioSource.clip = bgmClip;
audioSource.loop = true;
audioSource.Play();同じ GameObject の AudioSource を使い、クリップ・ループ・再生を Awake でそろえています。
Unity 6 で少し変わった点(Inspector)
Unity 6 では Inspector の表記が整理・変更されています。
- 以前は
AudioClipと表示されていた場所が、環境によってAudio ResourceやClipなどのラベルになっていることがあります。
コード側の型は変わらず AudioClip なので、[SerializeField] private AudioClip bgmClip; は Unity 6 でもそのまま通用します(見た目の名前が違うだけ、と捉えれば足ります)。
応用:BGM 以外にも効くパターン
今回の学びは「シーンをまたいで残したい状態」全般に効きます。
- サウンド管理
- スコアやセッション情報
- 設定(音量、言語、操作方式)
- プレイヤーの一時データ
など、**寿命が「1 シーン」ではなく「アプリ実行中」**のものを載せるときの定番が、DontDestroyOnLoad とシングルトンの組み合わせです。
まとめ
シーン切替後も BGM を継続するには、次をセットで理解すると強いです。
- シーンに置いたオブジェクトは基本、シーンと一緒に消える
DontDestroyOnLoadで破棄されない場所へ退避する- シングルトンでマネージャーの重複を潰す
AudioSourceでクリップ・ループ・再生を管理する
この「オブジェクトの寿命」の考え方は、Unity 制作のどこにでも顔を出します。BGM だけのテクニックではなく、ゲーム全体の設計の基礎として覚えておくと後が楽になります。