NullReferenceException: Object reference not set to an instance of an object
オブジェクトがセットされていない状態(nullな状態)で、メソッドを実行したりプロパティにアクセスした時に発生するエラーです。
自分の場合は、Awake()やStart()の中身に原因があることが多いです。厄介なことに、エディターで実行している時には発生せずにXcodeプロジェクトとしてビルド&実行した後で発生することがあります。おそらく、自分でスクリプトの実行順を指定しない限り、MonoBehaviourの同じメソッドの実行順は確定していないんだと思います。
エラーが発生するケースの例
CardOnStageクラスのAwake()で、子オブジェクトにアタッチされたLabelOwnerコンポーネントを取得し、続けてSetLabelメソッドを実行しています。
1 2 3 4 5 6 7 8 9 10 |
public class CardOnStage : MonoBehaviour { LabelOwner _labelOwner; void Awake() { this._labelOwner = transform.FindChild("_LabelOwner").GetComponent<LabelOwner>(); this._labelOwner.SetLabel(true); } } |
LabelOwnerクラスのAwake()で、UILabelコンポーネントを取得しています。
SetLabelメソッド内では、Awake()で取得済みのUILabelコンポーネントのtextプロパティへ値を設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class LabelOwner : MonoBehaviour { UILabel _uiLabel; static string _nameDealer = "DEALER"; static string _namePlayer = "PLAYER"; void Awake() { this._uiLabel = GetComponent<UILabel>(); } public void SetLabel(bool isDealer) { if (isDealer) { this._uiLabel.text = _nameDealer; return; } this._uiLabel.text = _namePlayer; } } |
上記2つのクラスのAwake()が
1. LabelOwnerクラス
2. CardOnStageクラス
の順番に実行されていればNullReferenceExceptionは発生しません。
実行順が逆になると問題が発生します。
CardOnStageクラスのAwake()のGetComponentは問題なく実行されますが、次のSetLabelメソッドの呼び出しで問題が発生します。この時点ではLabelOwnerクラスの_uiLabel変数にはUILabelコンポーネントが設定されていません(Awakeが実行されていない)。SetLabelメソッド内でtextプロパティに値を設定しようとした時にNullReferenceExceptionが発生してしまいます。
エラーを防ぐには
CardOnStageクラスのAwake()にあったSetLabelメソッドの呼び出しをStart()へ移動すれば問題は起きません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class CardOnStage : MonoBehaviour { LabelOwner _labelOwner; void Awake() { this._labelOwner = transform.FindChild("_LabelOwner").GetComponent<LabelOwner>(); } void Start() { this._labelOwner.SetLabel(true); } } |
スクリプトの実行順を指定するか、実行順が変わった時に問題が起きないように注意してコードを書く必要があります。
コメントを残す
コメントを投稿するにはログインしてください。