ゲームを作っていて、全体としてカウントダウンをManagerに任せるとして、でもそれをいろんなスクリプトで引用したいなあと思ったとき、どうするのかについて。
まず、UnityEngineにはGameObject.Find()という関数があって(というよりGameObjectというクラスがそういうメソッドを持っているだけで)、引数はオブジェクト名、つまり文字列。返り値はGameObjectクラスのインスタンス。これでManagerがアタッチされているオブジェクトを探し出す。
次に使うのはおなじみGetComponent<>()関数。これはもともとGameObjectクラスのメソッドらしいけど、それの書かれたスクリプトがアタッチされたオブジェクトに関してはGameObject.、みたいなのを書かなくて大丈夫なだけで、本来必要そう。だからthis.GetComponentと同値かな?といった感じ。で、これをFind関数で見つけたオブジェクトで実行すればよし。スクリプトのクラス名はもちろんスクリプトのファイル名と同じ。もしManagerにアタッチされているスクリプトの名前がManagerだったら、
Manager manager;
manager = GameObject.Find("Manager").GetComponent<Manager>();
とすればよい。スクリプトにはクラスしか記載がなく、インスタンスの生成について一切の記述がないはずだが、おそらく「オブジェクトにアタッチする」=「オブジェクトのコンポーネントに新しく生成したインスタンスを追加する」だと思うので、参照先はスクリプトのように見えてじつはスクリプトに記述されているクラスのインスタンスでしかないということにも注意が必要。
これであとはManagerクラスのインスタンスmanager内の変数をmanager. で参照してあげればよい。もちろんだが参照先の変数は宣言された際にアクセス修飾子がpublic でないと参照できない。
いままでほかのクラスの変数はconstで宣言されたものしか無理だと思っていたが、それはいつも参照の記述方法を(クラス名).変数名としてたからかな?そういう勘違いが起こってたのは。
クラス内でconstで宣言された変数(?)はクラスという「枠組み」のもつ「全員共通のパラメータ」、いわばみんなの常識として共有され、また不変であったからクラス名からでも参照できた、といったところかな?
あと分かったことは、クラス内で一括で変数であってもrandom.Range(a,b)とかでオブジェクトごとに同じ変数名でも、実際の値は違う!みたいなことができた。実際、今作っているゲームで正弦波で動く床の動きを、同じクラスの同じ関数で記述しながら、初期位相を変えることもできたしネ!
今度はそれぞれのオブジェクトが新しくコンストラクタを持つようにできればいいなあTagみたいに。
以上