🎨
【Unity】デザインパターン SingleTon
Unityの開発では、ゲーム進行や設定管理、オーディオ管理といったクラスが
「プロジェクト内に1つだけ存在する」ケースがよくあります。
このようなクラスを効率的に管理するために利用される、
「シングルトンパターン」について調べたので、内容をまとめてみました。
シングルトンパターンとは?
-
クラスのインスタンスを1つだけにすること
ゲーム全体を管理するGameManager
などは、複数存在すると混乱を招く可能性があります。 -
そのインスタンスにグローバルアクセス可能にすること
必要なときに、簡単にGameManager.Instance
としてアクセスできるようになります。
これにより、特定のクラスを1つに限定し、プロジェクト全体で共有できます。
シンプルなシングルトン
public class SimpleSingleton : MonoBehaviour
{
public static SimpleSingleton Instance;
private void Awake()
{
if (Instance == null)
{
Instance = this; // 初回生成時にインスタンスを設定
}
else
{
Destroy(gameObject); // 2つ目以降のインスタンスを破棄
}
}
}
特徴
-
Instance
フィールドを利用して、シングルトンのインスタンスを保持します。 -
Awake
メソッドで、既存のインスタンスが存在する場合は破棄する仕組みです。 - 注意点: この実装では、シーンをまたいでインスタンスを保持することはできません。
シーンをまたいで使うシングルトン
public class PersistentSingleton : MonoBehaviour
{
public static PersistentSingleton Instance;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject); // シーンを切り替えても破棄されない
}
else
{
Destroy(gameObject); // 2つ目以降のインスタンスを破棄
}
}
}
特徴
- 複数のシーンでインスタンスを保持するためには、
DontDestroyOnLoad
を使います。 - この仕組みを使えば、設定データやスコア管理など、シーン間で共有する必要があるクラスに適用できます。
ジェネリックを活用した汎用的なシングルトン
実装例
public class Singleton<T> : MonoBehaviour where T : Component
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
GameObject obj = new GameObject(typeof(T).Name);
instance = obj.AddComponent<T>();
DontDestroyOnLoad(obj);
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
利用例
public class GameManager : Singleton<GameManager>
{
public int Score { get; set; }
}
- シングルトンを複数クラスで再利用したい場合、ジェネリックを活用した実装が便利です。
-
GameManager.Instance
を利用して、どこからでもスコアを管理できます。
まとめ
シングルトンは、非常に便利で強力なデザインパターンですが、
使い方次第で大きなリスクを伴うこともあります。
安易に多用するとコードの独立性や可読性を損ない、
結果としてスパゲティコード化を招く危険性があります。
シングルトンを使用する際は、「本当に必要な場所にだけ利用する」という姿勢が重要です。
Discussion