UnityでMonoBehaviourのシングルトン

More than 3 years have passed since last update.

いろいろなところでかかれているから、何番煎じかわからんけど書いてみます。


SingletonMonoBehaviour.cs

using System;

using UnityEngine;

public abstract class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
Type t = typeof(T);

instance = (T)FindObjectOfType(t);
if (instance == null)
{
Debug.LogError(t + " をアタッチしているGameObjectはありません");
}
}

return instance;
}
}

virtual protected void Awake ()
{
// 他のGameObjectにアタッチされているか調べる.
// アタッチされている場合は破棄する.
if (this != Instance)
{
Destroy(this);
//Destroy(this.gameObject);
Debug.LogError(
typeof(T) +
" は既に他のGameObjectにアタッチされているため、コンポーネントを破棄しました." +
" アタッチされているGameObjectは " + Instance.gameObject.name + " です.");
return;
}

// なんとかManager的なSceneを跨いでこのGameObjectを有効にしたい場合は
// ↓コメントアウト外してください.
//DontDestroyOnLoad(this.gameObject);
}

}



NewBehaviourScript

using UnityEngine;

using System.Collections;

public class NewBehaviourScript : SingletonMonoBehaviour<NewBehaviourScript>
{
override protected void Awake()
{
// 子クラスでAwakeを使う場合は
// 必ず親クラスのAwakeをCallして
// 複数のGameObjectにアタッチされないようにします.
base.Awake();
}

}


SingletonMonoBehaviourを継承すればとりあえずできます。

実行時にプログラムなどで行うような(prefabにアタッチされInstantiateとか、AddComponent)のようなものではなく

用意されるシーンのHierarchyにはじめからあるGameObjectにアタッチして使うようなことを想定かも。

↓こんな感じでインスタンスは取得

NewBehaviourScript obj = NewBehaviourScript.Instance;