ここではC#スクリプトからゲームオブジェクトを検索して、その参照を取得する方法について説明します。
※この記事で使用しているUnityのバージョン:Unity2019.1
1つのゲームオブジェクトを検索して取得する方法
はじめに、シーン内から1つのゲームオブジェクトを検索して取得したい場合は次の3通りの方法があります。
- GameObject.Findで「ゲームオブジェクトの名前」から検索
- GameObject.FindGameObjectWithTagで「ゲームオブジェクトのタグ」から検索
- FindObjectOfTypeで「指定したクラス」を検索
GameObject.Find
シーン内でゲームオブジェクトの名前を検索し、一致する名前を持つ最初のゲームオブジェクト1つを取得します。
gameObject = GameObject.Find("Test");
GameObject.FindGameObjectWithTag
シーン内でゲームオブジェクトのタグを検索し、一致するタグを持つ最初のゲームオブジェクト1つを取得します。
gameObject = GameObject.FindGameObjectWithTag("TestTag");
タグで検索するので、3つの方法の中では1番処理が軽いです。
ちなみにFindWithTagというメソッドもありますが、FindGameObjectWithTagと全く同じ動作をするので好きな方を使ってOKです。
FindObjectOfType
シーン内から指定したクラスを検索し、一致する最初のクラスの参照を取得します。
gameObject = FindObjectOfType<GameObject>();
上記の例ではGameObjectクラスを検索して1つ取得します。これだと使いどころがよく分かりませんが、この方法の場合はゲームオブジェクトに限らず色々なクラスを取得できる(例えばFindObjectOfType<TestClass>()等)ので「あるクラスのコンポーネントを持っているゲームオブジェクトを検索したい」という場合に使えるかもしれません。
ただし、シーン内のゲームオブジェクトのコンポーネントまで見るので一番処理が重いです。
複数のゲームオブジェクトをまとめて検索して取得する方法
次に複数のゲームオブジェクトをまとめて検索して取得する方法です。このような場合のために、1つだけ取得する場合と似たような使い方のメソッドが用意されています。
- GameObject.FindGameObjectsWithTagで「ゲームオブジェクトのタグ」からまとめて検索
- FindObjectsOfTypeで「指定したクラス」をまとめて検索
先ほどの1つだけ取得する場合との違いは、戻り値が配列になっているという点だけです。
ゲームオブジェクトを検索するときの注意点
さて、ゲームオブジェクトを検索するときには1つ注意点があります。それはゲームオブジェクトの検索処理は重いということです。
なのでUpdate内で毎フレーム検索する、といったことはやらないほうが良いでしょう。
おまけ1:子を検索したい場合
それから余談ですが、あるゲームオブジェクトの子の中から名前で検索して取得したい場合はTransform.Findを使います。使い方はGameObject.Findと同様で
child = transform.Find("ChildName");
のように書くだけです(transformのところには親のトランスフォームを指定してください)。
なお検索に使う名前には階層を指定することもできます。例えば「Test/Name」と書けば、子のTestの中のNameという名前のゲームオブジェクト(つまり孫オブジェクト)のトランスフォームを取得できます。
おまけ2:GameObject.FindとTransform.Findの違い
ところでGameObject.FindとTransform.Findは似ていますが、一体どのような違いがあるのでしょうか?
主な違いは次の2つです。
- 検索する範囲
- 戻り値
検索する範囲が違う
まず1つ目は検索する範囲が違います。GameObject.Findはシーン全体を検索するのに対し、Transform.Findは自分の子だけを検索します。
戻り値も違う
2つ目は戻り値の違いです。GameObject.Findは戻り値がGameObject型、Transform.Findは戻り値がTransform型です。