【教えてください】UnityでMonoBehaviorでないSingletonはどうやる?
Singletonでいこう
世間ではUniRxやらZenjectでSingleton祭りを脱却しよう、みたいな記事がたくさん出ている。
だが、小規模アマチュア僕たちはSingleton祭りでいいんじゃないかなという気がしてしまう。
どうせゲームのTestは書きづらいということもあるし。
MonoBehaviorのSingletonは既に色々説明記事がある
qiita.com
tsubakit1.hateblo.jp
このようにMonoBehaviorのSingletonは既に色々説明記事がある。
が、「別にMonoBehaviorの機能いらないよ」という場合はコレで実装するのがどうも気が引ける。
MonoBehaviorに生えているプロパティやらメソッドの数は結構なものであるし、インテリセンスで余計なものがサジェストに大量に出てくるのも微妙だ。
MonoBehaviorでないSingletonを書く
MonoBehaviorでないSingleton実装方法としては、普通はこんな感じだろうか。
(非常にSingletonにされやすい音関係をイメージしてクラス名はSoundManagerとした)
public class SoundManager { private static SoundManager mInstance = null; public static SoundManager Instance { get { if (mInstance == null) { mInstance = new SoundManager(); } return mInstance; } } //privateなので var s = new SoundManager(); とかはできない private SoundManager() { } public void Play(string key) { ... }
これで、
SoundManager.Instance.Play("bang");
とか
var SoundManager soundManager = SoundManager.Instance;
soundManager.Play("bong");
とかすればフツーに使える。
newもできないのでたしかにSingletonとして機能している。
うまくいかない、SingletonBaseを継承するパターン
が、毎度毎度mInstanceのどうこうを書くのは非常にめんどい。
SingletonBase
public class SoundManager : SingletonBase<SoundManager> { private SoundManager() { } public void Play(string key) { ... }
とかできれば非常にラクで見やすい。
ところが、
public abstract class SingletonBase<T> where T : SingletonBase<T>, new() { private static T mInstance = new T(); public static T Instance { get { return mInstance; } } }
のように書いて継承するとエラーが起きてしまう。
(パブリックでないとダメだそうだ……)
SoundManagerコンストラクタをpublicにすればエラーはでないが……
その場合、
普通にnewできてしまう。
これではSingletonではない。