2011年10月19日水曜日

別のGameObjectにアクセス

Component詳細の前にGameObject検索に横道。
今までの例では、スクリプトに割り当てられたGameObjectを触っていました。
そして紐付けはUnityのGUIからドラッグ&ドロップだったため、実行前に決められていました。

じゃあ実行時に別のGameObjectを、、、という場合はどうでしょう。
複数方法がありますが、代表的なものがこちら。
  • 実行時にFindで検索
  • publicメンバにして実行前に紐付け
前者は速度的には厳しいですが、動的な生成破棄をするなら必須です。
後者はオブジェクト指向的に問題なのと、GUI操作必須ですが高速です。

まずは前者から。
GameObjectのstatic関数、Findで検索が可能です。
宣言はこんなかんじ。

static function Find (name : String) : GameObject

ヒエラルキー上で表示されている名前を入れると検索し、該当すればインスタンスが戻るという仕組みです。
しかしこの名前、GameObjectの最基底クラスであるObjectのnameメンバなのですが、シーン上でユニークな訳ではありません。
実際、シーン上には同じ名前のGameObjectがいっぱい作成できてしまいますし。
プレハブでもそうですが、名称を自力で固有に変更しなければ欲しいインスタンスにアクセスできないのでご注意を。

以下は具体例です。 (公式から抜粋)
このようにヒエラルキー構造を指定して検索を掛けることも可能です。
スラッシュから始まる検索の結果は、「ルートに存在するオブジェクトである可能性がある」と公式には書いてありますが、実際にはルートにあっても階層下にあっても検索できてしまいます。
/Monster/Armのように階層が深くユニークなら実質問題ないようです。

他にも手はあって、タグを利用した名前付けで検索することも可能です。

static function FindWithTag (tag : String) : GameObject

これもまたユニークというわけではないので自力で設定しましょう。
なお、遅いと言いましたが、Update()で書いたりすると恐ろしく遅くなります。
Awake等で検索し、自前メンバに保持しておくのが一般的です。


長くなりましたが続いて後者。
上記のコードでGameObjectのhandがpublicになっています。
オブジェクト指向の世界で、何も考えずにメンバをpublicにすることは通常ありません。
が、こうしておくと、Unityのインスペクタにそのメンバが表示されるようになります。
以前この値をGUIから変更可能と書きましたが、クラスメンバの場合はここから静的にインスタンスを指定することが可能です。
要は、Findでやることを実行前に確定させるだけの事。
反則感はありますが、これも推奨のようです。

そしてそのやり方は簡単。
publicなクラスメンバを持ったスクリプトをGameObjectに紐付けます。
そのGameObjectを選択すると、インスペクタのスクリプト欄にそのメンバが出ます。
ヒエラルキーからドラッグ&ドロップで終了。

未設定ならNoneに、入ってれば名称がでます。上書きもおk

なお、マテリアル等ならプロジェクトビューからでも紐付けできます。

0 コメント:

コメントを投稿