[Unity] コンポーネントのNULL参照を防ぐ

以下のようなスクリプトをGameObjectにアタッチしたとします。

using UnityEngine;
using System.Collections;

public class AirResistance : MonoBehaviour {
    public float coefficient;   // 空気抵抗係数

	void FixedUpdate() {
	    // 空気抵抗を与える
        rigidbody.AddForce(-coefficient * rigidbody.velocity);
	}
}

上記スクリプトでは同GameObject内のRigidbodyを参照しています。
しかし、RigidbodyがGameObjectにアタッチされていない場合はどうなるでしょうか?

Rigidbodyが無いため以下のような例外が発生してしまいます。

MissingComponentException: There is no ‘Rigidbody’ attached to the “Sphere” game object, but a script is trying to access it.

GetComponent()でコンポーネントを取得した場合はnullが返却されるため、この戻り値からメンバにアクセスしようとするとNullReferenceExceptionが発生します。

上記の問題はいずれも参照しようとしている型のコンポーネントが同GameObjectにアタッチされていれば問題ないですが、付け忘れた場合にはどうしようもありません。
このようなヒューマンエラーには以下の方法で対応できます。

・足りないコンポーネントを一緒に追加する
以下のようにスクリプトのクラス定義の前にRequireComponent属性を追加します。

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
public class AirResistance : MonoBehaviour {
    public float coefficient;   // 空気抵抗係数

	void FixedUpdate() {
	    // 空気抵抗を与える
        rigidbody.AddForce(-coefficient * rigidbody.velocity);
	}
}

typeof()の中に必要なコンポーネント型を指定します。
書き方についてはあまり深いことは考えなくても大丈夫でしょう。

これでAirResistanceコンポーネントをインスペクタから追加するときにRigidbodyも一緒に追加してくれます。

require-component

複数の型を指定したい場合は属性指定を以下のように書けばOKです。

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
[RequireComponent(typeof(MeshRenderer))]
public class AirResistance : MonoBehaviour {
    public float coefficient;   // 空気抵抗係数

	void FixedUpdate() {
	    // 空気抵抗を与える
        rigidbody.AddForce(-coefficient * rigidbody.velocity);
	}
}

必要なコンポーネント型を明示することで、スクリプト利用者にもこのことを知らせられるため何かと便利です。

■参考サイト
RequireComponentによるコンポーネントの追加忘れ防止 – Neareal
[RequireComponent]属性について ゴマちゃんフロンティア