GetComponentメソッドについて
GetComponentメソッドについて調べたり,まとめてみたりしました。 (Unity4.3.2f1で試しています。)
この記事はUnity4.3.2f1での記事です。ドキュメント化されていない仕様・挙動について他のバージョン・最新のバージョンでのUnityの動作を保証するものではありません。
3個のオーバーロード
Componentクラスのインスタンスメソッド,GetComponent。
このGetComponentメソッドは3個のオーバーロードを持っています。
Component GetComponent(Type type); T GetComponent<T>(); Component GetComponent(string type);
スクリプトリファレンスによるとパフォーマンスの観点から見て,文字列型を引数にとるオーバーロードより他の物を使った方がいいようです。
またGeneric Functionsにはジェネリクスを用いると,キャストをする手間とタイプする文字数が減るよねという記述があります。
基本的には,ジェネリクス版を使えばいいと思います。が,しかしジェネリクスのオーバーロードではできず,Type型を引数にとるオーバーロードではできるものがありました。
型パラメータにスーパークラスを与えてGetComponent
MonoBehaviourクラスを継承したBaseクラス。そのBaseクラスを継承したDerived0クラスを用意します。
using UnityEngine; public class Base : MonoBehaviour { }
public class Derived0 : Base { }
そして,Baseクラスを型パラメータに指定してGetComponentします。 そのGetComponentしたコンポーネントのクラス名を表示するクラスを作ります。
using UnityEngine; public class GetComponentSample : MonoBehaviour { void Start () { Base component = GetComponent<Base> (); Debug.Log (component.GetType ().Name); } }
次のようにシーン上のGameObjectにDerived0とGetComponentSampleコンポーネントをつけます。
これを実行すると,Derived0
とデバックログが出力されます。
サブクラスのコンポーネントが付与されているGameObjectに対して,スーパークラスの型を指定して,GetCompoenentでコンポーネントを取得することができました。
次のように,スーパークラスを抽象クラスにすることも可能なようです。
using UnityEngine; public abstract class Base : MonoBehaviour { }
また,次のようにDerive0とは違うサブクラスを作って,
public class Derived1 : Base { }
それを次のようにGetComponentSampleと一緒にGameObjectに付与して,
実行した場合,こちらはDerived1
と出力されました。
型パラメータにスーパークラスを指定したGetComponentメソッドの呼び出しで,サブクラスのコンポーネントを取得することができることがわかりました。
複数のコンポーネントが付与されてる場合のGetComponent
using UnityEngine; public class StringContainer : MonoBehaviour { public string value; }
using UnityEngine; public class GetComponentSample : MonoBehaviour { void Start () { StringContainer component = GetComponent<StringContainer> (); Debug.Log (component.value); } }
次の画像のように一つのGameObjectにStringContainerクラスを3個,GetComponentSampleを1個付与します。
これを実行すると,
デバックログにはvalue0
と表示されました。
インスペクターのMoveUpなどを用いて,コンポーネントの順番を変えます。
上の画像のような状態で実行するとデバックログにはvalue1
と表示されました。
また順番を変えて以下のようにします。
この状態で実行するとデバックログにはvalue2
と表示されました。
同じクラスのコンポーネントが複数付与されている場合,インスペクターにおける一番上のインスタンス(という言い方でいいのでしょうか?)が取得できるようです。
前の節で作ったBaseクラス,Derived0クラスそしてDerived1クラスを使ってみます。ふたたびBaseクラスでGetComponentして,クラス名を表示します。
using UnityEngine; public class GetComponentSample : MonoBehaviour { void Start () { Base component = GetComponent<Base> (); Debug.Log (component.GetType ().Name); } }
上の画像のように, GetComponentSampleクラス, Derived0クラス, Derived1クラス の順番でコンポーネントを付与します。
これを実行するとデバックログに,Derived0
と表示されました。
順番を変えます。
上の画像の用に GetComponentSampleクラス, Derived1クラス, Derived0クラス の順番でコンポーネントを付与したら
これを実行するとデバックログに,Derived1
と表示されました。
GetComponentでコンポーネントを取得する際,もし指定した型パラメータのクラスで取得出来るコンポーネントが複数ある場合は,インスペクター上で一番上の物が取得できるようです。
GetComponentsについて
複数のコンポーネントを取得するGetComponentsというメソッドがあります。
取得しようとするコンポーネントがGameObjectについていない場合,GetComponentではnullが帰ってきますが,GetComponentsでは空の配列が帰ってくるようです。
前節のStringContainerクラスとGetComponentsメソッドを用いたサンプルを作りました。
using UnityEngine; public class GetComponentSample : MonoBehaviour { void Start () { StringContainer[] stringContainers = GetComponents<StringContainer> (); foreach (var stringContainer in stringContainers) { Debug.Log (stringContainer.value); } } }
上の画像ようにGetComponentSampleを1個とStringContainerクラスのコンポーネントを複数付けて文字列valueを画像の用に設定し,実行すると
value0 value1 value2 value3
という順番で表示されました。
順番を変えます。
上の画像のように,順番を変えると実行結果は
value3 value2 value1 value0
となりました。
GetComponentsで取得した配列の要素の順番は,インスペクターで表示される順番と同じ順番のようです。
インタフェースでGetComponent
2019/03/17(日) 追記ここから
Unity 5.0からインターフェース型Tでも T GetComponent<T>()
が利用できるようになりました。
Unity 4系では、T GetComponent<T>()
のT
はComponent型の型引数制約が設定されていたため、インターフェースでのT GetComponent<T>()
はできませんでした。
もとの記事では、「インターフェースではできない」という旨の記述がありましたがUnity5からはできるので、その部分を削除しました。
追記ここまで
まとめとか
よく使うGetComponentメソッド。(あとGetComponentsメソッド) 型パラメータにスーパークラスや抽象クラスを指定するのは,いくつか使い方がありそうですね。インターフェースはどうでしょう。もしかした。
本当は全コンポーネントや,一つのGameObjectについている,全ての自作コンポーネントを取得する方法を調べていたら,細かいところが気になって書いたポスト。
次は,GetComponents<Component>
やGetComponents<MonoBehavoiour>
でコンポーネント全取得します。
関連リンク
- GetComponentのスクリプトリファレンス
http://docs.unity3d.com/Documentation/ScriptReference/Component.GetComponent.html
- ジェネリック関数
http://docs.unity3d.com/Documentation/Manual/GenericFunctions.html
- 暗黙の参照変換
http://msdn.microsoft.com/ja-jp/library/aa691284(v=vs.71).aspx
- 型パラメータ制約
http://msdn.microsoft.com/ja-jp/library/d5x73970(v=vs.90).aspx