テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

シングルトンなオブジェクトを作る

Unityでシングルトンを実現してみる

■シングルトン

シングルトンとはデザインパターンの一つで、
インスタンスが一つしか生成されない事」を保証する。

シングルトンパターン(wikipedia)
http://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

このパターンを使って作成したオブジェクトは、一つしかないため、
複数のオブジェクトがデータを重複して持つような事を避ける事ができる。
また、擬似グローバル変数的な使い方もできて、かなり使い勝手が良い。

具体的には、ゲーム開始時にFindでManagerクラスを探したり、
Managerをpublicにして、毎回D&Dでつないでいたりするのを避けられる。

■方法

Unityのシングルトンはちょっと特殊な書き方になる。
というのは、MonoBehaviourがnewを使えないため、
Awakeで初期化する必要がある。なので、こんな感じに書くみたい。

public class Singleton : MonoBehaviour {

private static Singleton instance = null;
public static Singleton Instance {
get { return Singleton.instance; }
}

void Awake()
{
if( instance == null)
{
instance = this;
}else{
Destroy( this );
}
}
}

呼び出す場合、適当なオブジェクトにアタッチしてあるなら
下のようなコードでどこからでも呼び出せる。

Singleton s = Singleton.Instance;


■説明と問題点

これはStaticで全Singletonクラス共通のインスタンス(自分)を宣言して、
それが未登録なら自分を登録、登録済みなら自殺する、といった感じの事をしている。

とは言え、これではまだ不完全。
SingletonをオブジェクトにアタッチしないとInstanceはNullが入ってしまう。
ただMonobehaviourを継承しているオブジェクトはGameObjectに
アタッチしないと使えないし、これはこれで良いんじゃなないかなと思ってたり。
必要なら、InstanceがNullだった時にプレハブ読んだりすれば良いかも。


ちなみにMonobehaviourを使わないなら、一般的な書き方で問題ない。
単純にデータを保存したいだけなら、こっちを使った方が良いかも。
namespaceも使えるしね。

ただその場合、スレッドセーフに組まないと事故が起こるかもしれないので注意。



追記

[Unity3D]もっと楽なシングルトンの実装
http://terasur.blog.fc2.com/blog-entry-311.html