シングルトン
シーンに一つだけのビヘイビアを、どこからでも Type.Instance で。
ワールドにはたいてい「一つしかないもの」があります。試合、ショップ、ドアの管理役。他のすべてのビヘイビアがそれに触りたがり、インスペクタから一本ずつ参照を張るやり方は、二十個になるまでは通用します。誰も配線を覚えていない新しいプレハブが増えるまでは。
Singleton<T> を継承します。
using Udonite;
public class GameManager : Singleton<GameManager>
{
public int score;
public void Award()
{
score = score + 1;
}
}
GameObject に一つ置き、名前は好きにつけて、あとはどのビヘイビアからでも呼べます。
GameManager.Instance.Award();
属性も、自分で書くアクセサも、ドラッグする参照も要りません。オブジェクトの名前にも一切依存しません。Instance の読み取りは軽いので、Update の中で気にせず使えます。
シーンに一つであることは、編集中に確かめられます
二つあると、コンソールが両方のオブジェクトを挙げ、メッセージをクリックするとその一方が選択されます。
Udonite: GameManager is a Singleton<GameManager> and there are 2 in the scene:
'Managers/GameManager', 'Spawn/GameManager'. A singleton is one behaviour, and
nothing can choose between these. Delete the extras.
一つもない場合もそう伝えられ、置くまではシーン中の GameManager.Instance はどれも何にも解決しません。
どちらも Udonite がコンパイルするたびと、シーンを保存するたびに確認されるので、二つ目をオブジェクトにドラッグしてしまってもその場で分かります。
種類の違うシングルトンが複数あるのは普通のことです。それぞれ別に見つけられるので、一方が他方を渡してくることはありません。
参照は先に使えて、値は後から入ります
GameManager.Instance は最初のフレームから使えます。GameManager が自分の Start で入れるものは、まだかもしれません。
Unity はすべての Start をどの Update よりも先に走らせます。ワールドはそうしません。 そして Play モードではこの違いが見えないので、アップロードする前に知っておく価値があります。
public override void Update()
{
label.text = GameManager.Instance.score.ToString(); // 問題ない
title.text = GameManager.Instance.title; // 1 フレーム目は空かもしれない
}
確実な対処は二つ。インスペクタで値を入れておくこと。これは Start より前に入っています。
public string title = "Match";
あるいは、フレーム数ではなく値そのものを待つこと。
public override void Update()
{
if (ready)
return;
if (GameManager.Instance.title == "")
return;
ready = true;
// ここからは安全
}
参照そのものを待つ必要はありません。
static フィールドにインスタンスを持たせることはできません
public static GameManager Instance; // UDN0002
ワールドのビヘイビアはそれぞれ自分のメモリを持つので、static フィールドはビヘイビアどうしで共有されません。二つのビヘイビアはそれぞれ自分の写しを持ち、どちらも相手の書き込みを見られません。ワールドが静かに食い違うくらいなら、Udonite は断ります。
一つしかないものを持つ方法は Singleton<T> です。変わらない値なら const や static readonly は今までどおり使えます。