
【Unity】シングルトンとは
シングルトンとは
インスタンスが1つしか存在しないようにする仕組みのことです。
インスタンスというのは、実体(実際に動くもの)のことです。
よくある例えで、「クラス」は設計図、「インスタンス」はその設計図から作った本物の車(=実物)というのがあります。
なぜシングルトンが必要なのか?
ゲームを作るとき、「全体で一つだけ存在してほしい」ものがあると思います。
例えば、ゲーム内の設定管理や音量管理、セーブ管理などです。
これらが複数存在すると、設定が上書きされたり、バラバラのセーブデータが作られたり、音量の調整が片方にだけ反映されたりと、予期しないバグの原因になります。
スクリプトの参照は GetComponent
や FindAnyObjectByType
などでもできますが、
シングルトンを使うと「1つだけ存在する」ことが保証されているため、どこからでも簡単にアクセスできてとても便利です。
Unityでのシングルトンの基本的な書き方・使い方
書き方
public class GameManager : MonoBehaviour
{
public static GameManager instance; // インスタンスの定義
private void Awake(){
if (instance == null)
{
instance = this; // 自分をインスタンスに設定
}
else
{
Destroy(gameObject); // 複数存在していた場合、自身を破棄
}
}
}
public static GameManager instance;の意味
- public : どこからでもアクセスできる
- static : インスタンスではなくクラスに属する
- GameManager : 型名
- instance : 変数名
publicでGameManager型のinstanceという名前の変数を定義してます。
ここに static(静的)をつけることで、この変数はインスタンスに属さず、クラスそのものに属するようになります。
これの何がありがたいかというと、この GameManager スクリプトにアクセスするときに、GetComponent
や new
を使わずに直接アクセスできるようになるという点です。
また、その後はGameManager型の変数を宣言したあと、Awake時に instance が null なら、自分自身を代入しています。
こうして、自分をシングルトンのインスタンスとして設定できたわけですね!
もしすでに instance に別のインスタンスが入っていた場合は、重複を避けるためにDestroy
で自分を破棄しています。
使い方
ここではコインを取得した時に、GameManager
の score
の値を操作する例を見てみましょう。
例えば、以下のような GameManager
と Coin
のスクリプトがあったとします。
GameManagerスクリプト
using UnityEngine;
public class GameManager : MonoBehaviour
{
public int score = 0;
public static GameManager instance; // インスタンスの定義
private void Awake()
{
if (instance == null)
{
instance = this; // 自分をインスタンスに設定
}
else
{
Destroy(gameObject); // 複数存在していた場合、自身を破棄
}
}
}
Coinスクリプト
using UnityEngine;
public class Coin : MonoBehaviour
{
public void GetCoin()
{
GameManager.instance.score++;
Debug.Log("スコア: " + GameManager.instance.score);
}
}
この時、Coin
スクリプト内で GameManager.instance.score++;
でGameManager
にアクセスして、score
の値を+1
してます。
このように、他のスクリプトから GameManager.instance.score++
のように GameManager.instance
を通じて、score
などの変数にアクセス・操作できます。
補足
通常、シーンをまたぐと、そのインスタンスが破棄されてしまいますが、Awake
内に DontDestroyOnLoad(gameObject);
を追加することで、シーンをまたいでも同じ GameManager
インスタンスを使い続けることができます。
ジェネリックを使った汎用的なシングルトン
先ほどの方法でもシングルトンは作れますが、シングルトンにしたいスクリプトごとに同じコードを書くのは少し面倒です。
そこで、ジェネリックな基底クラスというのを作成することで、コードの重複を減らし、使いやすくできます。
まずは、下記のような Singleton
クラスを作成します。
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T instance; // インスタンスの定義
protected virtual void Awake()
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T)); //探したコンポーネントをインスタンスに設定
}
else
{
Destroy(gameObject); // 複数存在していた場合、自身を破棄
}
}
}
public class Singleton<T> : MonoBehaviour where T : MonoBehaviourの意味
- public : どこからでもアクセスできる
- Singleton : クラス名
- <T> : あとで決める「型の名前」(ジェネリック型パラメータ)
- MonoBehaviour : Unityの基本クラス
MonoBehaviour
を継承 - where T : MonoBehaviour : Tは MonoBehaviour またはその派生クラスでなければならないという型の制限
ジェネリック(generics:総称型)とは
ジェネリックはさまざまな型に対応するために、型をパラメータとして受け取る仕組みのことです。
Singleton<T>
は「Tという型のシングルトンを作るためのテンプレート」になっています。
where T : MonoBehaviourの意味
where T : MonoBehaviour
と指定することで、T
に int
や string
のような型が入るのを防ぎます。
これにより、Unity のコンポーネント(MonoBehaviour 派生クラス)だけを対象にできます。
間違った型を指定するとコンパイルエラーになるので、安全です。
instance = (T)FindObjectOfType(typeof(T));の意味
- instance : シングルトンのインスタンスを格納する変数
- FindObjectOfType(typeof(T)) : シーン内にある型
T
のコンポーネントを探すUnityの関数 - (T) :
FindObjectOfType
の返り値はObject
型なので、型T
に変換(キャスト)する
まとめると、シーン内に既にある T
型のコンポーネントを探して、正しく型変換し、それを instance
に代入するという処理を行っています。
この Singleton
クラスがあれば、たとえば GameManager
をシングルトンにしたいときは、以下のように書くだけでOKです。
using UnityEngine;
public class GameManager : Singleton
{
// GameManager に関する処理
}
普段 MonoBehaviour
と書いていたところを Singleton<GameManager>
にすることで、
GameManager
クラスはSingleton<GameManager>
を親クラス(=継承先)として使うSingleton
クラスに書かれた「シングルトンの仕組み」をそのまま使える
という形になります。
これで毎回シングルトンのコードを書かなくて良くなりました!
まとめ
今回は、シングルトンの概念と使い方について解説しました。
シングルトンとは、インスタンス(実体)が常に1つだけしか存在しないようにする仕組みだということが分かりましたね。
ちなみに、シングルトンはデザインパターンと呼ばれる設計手法の1つなので、
たとえばファクトリーパターン(Factory Pattern)、オブジェクトプール(Object Pool)など、他にもさまざまな種類があります。
これらのパターンについても、今後少しずつ紹介していけたらと思います!
参考
- Unity Documentation - 静的ゲームオブジェクト(参照日: 2025 年 06 月 19 日)
- twugo - シングルトンパターン(Singleton Pattern)(参照日: 2025 年 06 月 19 日)
- umi studio blog - 【Unity】シングルトンとは?初心者にもわかりやすく解説!(参照日: 2025 年 06 月 19 日)
- ソフトライム - 【Unity】Unityでシングルトンを使う用途(参照日: 2025 年 06 月 19 日)
- Microsoft - ジェネリック クラスとメソッド(参照日: 2025 年 06 月 19 日)