コンポーネントの追加
オブジェクトにコンポーネントを追加する
シーンに配置されるあらゆるゲームオブジェクトは、設定されているコンポーネントによって役割を決定します。カメラ、照明、地形、サウンド、キャラクターなど、ゲーム内のあらゆるものはゲームオブジェクトであり、コンポーネントの組み合わせによって役割を変化させます。
コンポーネントは、種類に応じてゲームオブジェクトに独自の振る舞いを提供します。Unity で標準提供多くのコンポーネントに加えて、MonoBehaviour クラスを継承しているスクリプトもまたコンポーネントの一種です。オブジェクトの描画や照明、サウンドの再生、物理効果など、すべてはコンポーネントによって実行されます。
あらゆるコンポ―ネントは UnityEngine.Component クラスから派生しています。MonoBehaviour クラスもまた Component クラスから派生しており、スクリプトはコンポーネントの一種として機能しています。
UnityEngine.Object UnityEngine.Component
public class Component : Object
例えば、ゲームオブジェクトに対するコンポーネントをスクリプトから制御することで、ゲーム実行時にゲームオブジェクトが実行するスクリプトを追加したり削除したりできます。
ゲームオブジェクトにコンポーネントを追加するには AddComponent() メソッドを使います。
public Component AddComponent(string className)
public Component AddComponent(Type componentType)
public T AddComponent<T>() where T : Component
className パラメータにはコンポーネントの型を文字列で、componentType パラメータにはコンポーネントの型を表す Type オブジェクトを指定します。コンポーネントのインスタンス化はメソッドの内部で行われ、生成したコンポ―ネントを結果として返します。
T 型パラメータを受け取る、ジェネリック化された AddComponent() メソッドは T 型パラメータに指定したコンポーネントを生成し、生成したコンポーネントを T 型として返します。型安全に結果を受けられるため AddComponent() メソッドの結果を使う場合は、ジェネリック化された AddComponent() メソッドを使うと良いでしょう。
using UnityEngine; public class Sample : MonoBehaviour { void Start() { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent(typeof(RotateSample)); } }
using UnityEngine; public class RotateSample : MonoBehaviour { void Update () { transform.Rotate(0, 1, 0); } }
コード1の Sample クラス(Sample.cs)を実行すると、新しい立方体プリミティブを生成し、このオブジェクトに RotateSample クラスをコンポーネントとして登録します。実行すると、動的に生成されたゲームオブジェクトに対し、指定した RotateSample クラスがコンポーネントとして追加されていることが確認できます。
追加したコンポーネントを削除するには、ゲームオブジェクトが持つ Component オブジェクトを Destroy() メソッドに渡します。
using UnityEngine; public class Test : MonoBehaviour { private Component component; void Start() { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); component = cube.AddComponent(typeof(RotateSample)); } void Update() { if (Time.time > 10 && component != null) { Object.Destroy(component); component = null; } } }
コード2はコード1を改良したもので、RotateSample クラスの中身は同じです。このプログラムは、生成したゲームオブジェクトに RotateSample クラスをコンポ―ネントとして追加しています。ここまではコード1と同じですが、 AddComponent() メソッドが返したオブジェクトをフィールドに保存し 10 秒後にコンポーネントを Destroy() メソッドに渡して削除しています。
通常、AddComponent() で追加したコンポーネントを受け取る場合、ジェネリック化された AddComponent<T>() を使います。文字列や Type 型で追加するコンポーネントの型を受け取るメソッドは、その結果を基底クラスの Component 型として返します。
Component component = obj.AddComponent(typeof(Sample));
例えば、上記のコードは Sample 型のコンポーネントを追加し、その結果を受け取っています。この AddComponent() は Type 型を受け取るオーバーロードなので、結果は Component 型となります。追加したコンポーネントの具現型である Sample 型ではありません。これを Sample 型として操作するには、変換が必要です。
Sample component = obj.AddComponent(typeof(Sample)) as Sample;
Component 型を返す AddComponent() メソッドの結果を利用する場合、型キャスト演算子や as 演算子を用いて上記のように変換できます。しかし、このように追加したコンポーネントを取得する場合はジェネリック化された AddComponent() メソッドを使うと便利です。
Sample component = obj.AddComponent<Sample>();
このように、typeof や型変換が不要になり、追加したコンポーネントを、そのまま受け取れます。
using UnityEngine; public sealed class Sample : MonoBehaviour { void Start () { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); RotateSample component = cube.AddComponent<RotateSample>(); component.Angles = new Vector3(0, 1 , 2); } }
using UnityEngine; public class RotateSample : MonoBehaviour { public Vector3 Angles { get; set; } void Update () { transform.Rotate(Angles); } }
コード3はコード1を改良し、RotateSample クラスに回転させる角度を指定する Angles プロパティを追加しています。このスクリプトをコンポーネントとして追加する Sample クラスでは、AddComponent() メソッドで RotateSample コンポーネントを追加した結果を受け取り、プロパティを設定しています。
このように、AddComponent() メソッドでコンポーネントを追加し、その結果を抽象的な Component 型ではなく、追加したコンポーネントの実体と同じ型として受け取りたい場合はジェネリック化された AddComponent() メソッドの型パラメータとして追加するコンポーネントを指定します。この場合、メソッドの戻り値は T 型パラメータなので、型安全にコンポーネントを受け取れます。
コンポーネントの取得
ゲームオブジェクトに設定されているコンポーネントは GetComponent() メソッドから取得できます。
public Component GetComponent(Type type)
public Component GetComponent(string type)
public T GetComponent<T>() where T : Component
取得したいコンポーネントの種類は型で指定します。type パラメータには、コンポーネントの型を表す Type オブジェクト、または文字列を指定します。T 型パラメータを指定した場合、型パラメータに一致するオブジェクトが返されます。一致する型のコンポーネントを持たない場合は null が返されます。
using UnityEngine; public class Test : MonoBehaviour { private GameObject cube; private const string SCRIPT_NAME = "RotateSample"; void Start() { cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent(SCRIPT_NAME); } void Update() { if (Time.time > 10) { Component component = cube.GetComponent(SCRIPT_NAME); if (component != null) Object.Destroy(component); } } }
コード4はコード2を改良し、追加したコンポーネントを保持せず Update() メソッドで GetComponent() メソッドから削除するコンポーネントを取得していますコード4では、文字列を用いて追加および取得するコンポーネントを指定していますが、結果は Type オブジェクトやジェネリックを用いた場合と同じです。ただし、特別な理由がなければ、より安全なジェネリック化されたメソッドを使うべきでしょう。