【Unity】NullReferenceExceptionのエラーと対策

本日のテーマ

「NullReferenceException」の原因と対策

 

NullReferenceExceptionとは

NullReferenceException』とは、

オブジェクトの参照が切れているときに発生するエラーのことです。

 

もっと噛み砕いた言い方をするなら、

「そんなオブジェクト見つからないよ?」

「どのオブジェクトのことをいってるの?」

と、このよう状況のときに発生するエラーです。

 

エラーメッセージの内容

UnityエディターのConsole(コンソール)画面に、

このようなエラーメッセージが表示されます。

エラーメッセージ2行目に、

エラーが発生した関数(Example.Start())と、

エラーが出たファイルとその行数(Assets/Scripts/Example.cs:12)

が表示されています。

 

エラーが起こった場所の特定に利用できます。

このエラーメッセージをダブルクリックすることで、

エラー箇所に飛ぶ(そのスクリプトを開く)こともできるので非常に便利です。

 

3つの原因と対策

では、どういった場面で「NullReferenceException」のエラーが起こるのか。

ポイントは3つです。

 

スクリプトで定義した変数の初期化を行っていない

このスクリプトでは、

“player”というGameObjectを定義しているが、初期化が行われずに使用されています。

 

[原因]

スクリプトで定義したGameObjectを、初期化することなく使用した。

 

[対策]

Find関数を使ってシーン内(Hierarchy)からGameObjectを取得したり、

Prefabを使ってGameObjectを生成するなどして、

しっかりと初期化を行ってください。

 

こちらが、Find関数を使った正しいスクリプトになります。

 

 

続いては、

上記のようにFind関数を使って、しっかりと初期化したにもかかわらず、

NullReferenceExceptionのエラーが出る場合です。

 

Find関数でGameObjectの取得に失敗している

スクリプトには問題ないが、NullReferenceExceptionのエラーが出る場合があります。

これはFind関数を使ってGameObjectを取得している場合に発生して、

原因は2つあります。

 

[原因1]

そもそも指定したGameObjectがScene内に存在していない

存在していないのだから取得できなくて当然ですよね。

もちろん、指定したGameObject名のスペルミスの場合も同様です。

 

[対策]

Scene内(Hierarchy)にGameObjectが間違いなく存在していること、

指定したGameObject名に間違いがないことを確認してください。

 

 

[原因2]

Find関数で取得するGameObjectが非アクティブになっている。画像2image2

見落としがちですが、

GameObjectが非アクティブ、すなわち「チェックが外れた状態」になっていると、

GameObject.Findでは、GameObjectを取得することができずにnullが返されます。

結果、NullReferenceExceptionのエラーが発生します。

 

[対策]

GameObjectをアクティブに設定することです。

どうしても非アクティブのままにしたい場合には、

GameObject.Find()ではなく、Transform.Find()を使用するようにしてください。

説明すると長くなってしまうので、当記事では割愛させていただきますが、

詳しくは「さよならエラー!『Find関数』を深く理解する!」をご覧ください。

 

 

インスペクターでGameObjectの初期化を行っていない

UnityエディタのInspector(インスペクター)で、

初期化しなければならないGameObjectの初期化を忘れている場合にも、

NullReferenceExceptionのエラーが発生します。


[原因]

インスペクターでGameObjectの初期化を行っていない。

 

[対策]

エラーメッセージを見て、

エラーが出ているスクリプトがアタッチされているGameObjectのインスペクターで、

GameObjectを正しく設定してください。

 

まとめ

NullReferenceExceptionのエラーが発生したときのチェックポイントです。

1.スクリプトで定義したGameObjectの初期化し忘れがないか

2.Find関数を使っている場合、GameObjectの指定を間違っていないか

3.GameObject.Findを使っている場合、GameObjectが非アクティブになっていないか

4.インスペクター上で、GameObjectの初期化し忘れがないか

 

これで、NullReferenceExceptionのエラーと対策の解説を終わります。