UnityでGameManagerやAudioManagerを作っていると、「どこからでも呼び出せる管理用スクリプトを1つだけ置きたい」と感じる場面がありますよね。そこでよく使われるのがSingleton(シングルトン)です。
ただ、見よう見まねで実装すると、シーン切り替え後に同じManagerが増えたり、Instanceがnullになったりして、原因を探すのに時間がかかることがあります。
この記事では、UnityでSingletonを使うべき場面を整理しながら、実装方法と失敗しやすいポイントを順番に見ていきます。
Singletonを使うべき場面
Singletonは便利な設計ですが、すべてのスクリプトに使うものではありません。
判断に迷ったら、「ゲーム全体で1つだけあれば十分な役割かどうか」を基準に考えると分かりやすくなります。
1つだけで十分な管理役に使う
Unityでは、次のような「ゲーム全体を管理する役割」のスクリプトでSingletonがよく使われます。
- GameManager(ゲーム全体の進行管理)
- AudioManager(BGM・効果音の管理)
- SaveManager(セーブデータの管理)
- 設定情報やゲームオプションの管理
これらは複数存在すると、設定が食い違ったり、BGMが二重に再生されたりと、不具合の原因になりやすい管理役です。そのため、「常に1つだけ存在する」というSingletonの考え方と相性がよくなります。
反対に、敵キャラクターや弾、アイテムのように複数生成されるオブジェクトには、Singletonは基本的に向いていません。
Singletonを採用するか迷ったら、次のチェックリストを確認してみてください。
- シーンをまたいで同じ情報を使いたい
- ゲーム内に1つだけ存在すれば十分な役割である
- 複数のスクリプトから共通で参照したい
この3つすべてに当てはまるなら、Singletonを採用する価値があります。
逆に、どれか1つでも当てはまらない場合は、通常のMonoBehaviourやScriptableObjectなど、別の方法のほうがシンプルに実装できることもあります。

まずは「本当に1つだけ必要なオブジェクトか」を判断し、そのうえで実装を始めることが、あとから設計を見直す手間を減らすポイントです。
UnityのSingleton基本実装
Singletonを使う場面が決まったら、まずは基本形を作ってみましょう。ここでは、UnityのMonoBehaviourを使った管理用スクリプトを想定します。
まずはこの形で作る
例として、ゲーム全体を管理するGameManagerをSingletonにするコードです。
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
}
}
外部のスクリプトから使うときは、次のように呼び出せます。
GameManager.Instance
Instanceには、現在使うべきGameManager自身が入ります。private setにしているので、ほかのスクリプトから勝手に中身を書き換えにくい形です。
Awakeでは、すでに別のGameManagerが存在しているかを確認しています。もし存在していれば、新しく作られたほうをDestroy(gameObject)で削除します。
このコードで防げる失敗
この基本形で防げる代表的な失敗は、同じManagerが複数存在してしまうことです。
- シーン内に同じManagerを2つ置いてしまった
- PrefabからManagerを重複生成してしまった
- 別シーンに同じManagerを配置していた
このような状態になると、スコアが別々に管理されたり、同じ処理が2回実行されたりすることがあります。見た目では気づきにくいので、最初から重複チェックを入れておくと安心です。

ただし、このコードだけではシーンを切り替えたときにオブジェクトは破棄されます。シーンをまたいで同じManagerを使いたい場合は、次のセクションで扱うDontDestroyOnLoad対応が必要になります。
シーンをまたぐなら永続化する
タイトル画面からゲーム画面へ移動したあとも、同じManagerを使い続けたい場合は、DontDestroyOnLoadを使います。
たとえば、BGMをシーン切り替えで止めたくないときや、ゲーム設定・スコア情報を次のシーンに引き継ぎたいときです。
DontDestroyOnLoadを追加する
基本実装にDontDestroyOnLoad(gameObject)を追加すると、シーンが切り替わってもそのオブジェクトが破棄されにくくなります。
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
この形にすると、最初に作られたGameManagerが残り続けます。ゲーム全体で共通して使う管理役には便利です。
重複生成防止も必ず入れる
DontDestroyOnLoadを使うときに忘れやすいのが、重複生成の対策です。
たとえば、タイトルシーンにもゲームシーンにも同じGameManagerを置いていると、シーン移動時に新しいGameManagerが作られることがあります。
そのまま放置すると、BGMが二重に流れたり、スコア管理がずれたりする原因になります。そこで、すでにInstanceが存在する場合は、あとから作られたほうを削除します。
- BGMをシーン移動後も流し続けたい
- タイトル、ゲーム、リザルトで同じ設定を使いたい
- プレイヤーデータやスコアを一時的に保持したい
このような場合は、DontDestroyOnLoad対応のSingletonを使うと管理しやすくなります。
一方で、シーンごとに別々の状態を持たせたいManagerには向きません。毎回リセットしたい情報まで残してしまうと、前のシーンの値が残って予想外の動きになることがあります。
BGMを止めずにシーンを移動する具体例は、こちらの記事でも解説しています。
Singletonでエラーになる原因
Singletonの実装でつまずきやすいのは、コードの書き方そのものよりも「呼び出すタイミング」と「破棄された後の参照」です。
とくに多いのは、Instanceがnullになるケースと、削除済みのオブジェクトを参照してしまうケースです。
Awakeの順番でnullになる
Unityでは、複数のスクリプトのAwakeがどの順番で実行されるかに注意が必要です。
たとえば、あるスクリプトのAwakeで次のように呼び出すとします。
private void Awake()
{
GameManager.Instance.StartGame();
}
このとき、GameManager側のAwakeがまだ実行されていないと、Instanceが設定されておらず、nullになることがあります。
判断基準としては、次のように考えると安全です。
Awakeでは、自分自身の初期化を中心にする- ほかのSingletonを使う処理は、できれば
Start以降に回す - どうしても順番が必要な場合だけ、Script Execution Orderを検討する
最初のうちは、Awakeで別のManagerを呼び出しすぎないようにすると、原因不明のnullをかなり減らせます。
Destroy後の参照が残る
もう1つ注意したいのが、破棄されたオブジェクトへの参照です。
Singletonのオブジェクトを削除したあとも、Instanceに古い参照が残っていると、存在しないオブジェクトを使おうとしてエラーになることがあります。
その対策として、OnDestroyで自分自身がInstanceならnullに戻しておきます。
private void OnDestroy()
{
if (Instance == this)
{
Instance = null;
}
}
ただし、DontDestroyOnLoadでゲーム中ずっと残すManagerの場合、通常プレイ中に何度も破棄することは少ないです。それでも、シーンの作り直しやテスト中には役立つことがあります。
次のような症状が出る場合は、破棄後の参照を疑ってみてください。
- シーンを戻ったあとにエラーが出る
- Play Modeを何度か試すと挙動が変わる
- 削除したはずのManagerを別スクリプトが呼んでいる
削除済みオブジェクト参照の詳しい考え方は、こちらの記事でも解説しています。
Singletonを使わない判断基準
Singletonは便利ですが、「どこからでも使えるから」という理由だけで増やしていくと、あとから管理が難しくなることがあります。
使うか迷ったときは、「本当に1つだけ存在する管理役なのか」をもう一度確認してみましょう。
データだけならScriptableObjectを検討する
アイテム情報や敵のステータス、ゲーム設定のように「値を持っておきたいだけ」の場合は、SingletonよりもScriptableObjectのほうが扱いやすいことがあります。
| やりたいこと | 向いている方法 |
|---|---|
| ゲーム中の進行状態を管理したい | Singleton |
| アイテムや敵の固定データを管理したい | ScriptableObject |
| シーンをまたいでBGMを管理したい | Singleton + DontDestroyOnLoad |
たとえば「ポーションの回復量」「敵の最大HP」「武器の攻撃力」のような固定データは、Singletonで管理するより、データとして分けたほうが見通しがよくなります。
判断基準はシンプルです。ゲーム中に状態が変わる管理役ならSingleton、あらかじめ決まったデータを参照したいだけならScriptableObjectを検討するとよいです。
大規模化したらDIも候補にする
プロジェクトが大きくなると、Singleton同士が互いに呼び合って、どこで何が動いているのか追いにくくなることがあります。
次のような状態になってきたら、Singletonを増やす前に設計を見直すサインです。
- Managerという名前のスクリプトが増えすぎている
- 1つのManagerが音・UI・セーブなど複数の役割を持っている
- 修正した場所とは別の機能まで壊れやすい
- どのスクリプトがどのManagerを使っているか追いにくい
この場合は、依存性注入(DI)や責務分離を検討すると、コードのつながりを整理しやすくなります。
ただし、小さな個人制作や学習用プロジェクトで、GameManagerやAudioManagerを1つだけ使う程度なら、無理に難しい設計へ進む必要はありません。
DIについて詳しく知りたい場合は、こちらの記事で基本を解説しています。
まとめ:まずは基本形で十分
UnityでSingletonを使うなら、まずは「本当に1つだけ必要な管理役か」を確認してから実装すると失敗しにくくなります。
GameManagerやAudioManagerのように、ゲーム全体で1つだけあればよいスクリプトなら、重複生成を防ぐ基本形から始めて大丈夫です。シーンをまたいで残したい場合だけ、DontDestroyOnLoadを追加しましょう。
一方で、固定データの管理や大規模な設計までSingletonでまとめようとすると、あとから修正しづらくなることがあります。迷ったときは「管理役ならSingleton、データだけなら別管理」と考えると、次に取る行動を決めやすくなります。
よくある質問(FAQ)
- QSingletonとstaticは同じですか?
- A
同じではありません。Singletonは「インスタンスを1つだけ使うための設計」、
staticは「インスタンスを作らずに使う仕組み」です。Unityでは、
MonoBehaviourの機能を使いたい場合はSingleton、単純な計算処理や定数だけを扱う場合はstaticが向いています。
- QSingletonは使わないほうがいいですか?
- A
使いすぎには注意が必要ですが、目的がはっきりしていれば使っても大丈夫です。
たとえば、GameManagerやAudioManagerのように「ゲーム全体で1つだけあればよい管理役」なら、Singletonは分かりやすい選択肢になります。
ただし、敵・アイテム・UIパーツのように複数存在するものや、固定データを持つだけのものまでSingletonにすると、後から整理しづらくなります。迷ったときは「1つだけ必要な管理役かどうか」で判断してみてください。










※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。