「NullReferenceException」の原因と対策
目次
NullReferenceExceptionとは
『NullReferenceException』とは、
オブジェクトの参照が切れているときに発生するエラーのことです。
もっと噛み砕いた言い方をするなら、
「そんなオブジェクト見つからないよ?」
「どのオブジェクトのことをいってるの?」
と、このよう状況のときに発生するエラーです。
エラーメッセージの内容
UnityエディターのConsole(コンソール)画面に、
このようなエラーメッセージが表示されます。
エラーメッセージ2行目に、
エラーが発生した関数(Example.Start())と、
エラーが出たファイルとその行数(Assets/Scripts/Example.cs:12)
が表示されています。
エラーが起こった場所の特定に利用できます。
このエラーメッセージをダブルクリックすることで、
エラー箇所に飛ぶ(そのスクリプトを開く)こともできるので非常に便利です。
3つの原因と対策
では、どういった場面で「NullReferenceException」のエラーが起こるのか。
ポイントは3つです。
スクリプトで定義した変数の初期化を行っていない
1 2 3 4 5 6 7 8 9 10 11 12 |
using UnityEngine; public class Example : MonoBehaviour { private GameObject player; // GameObject[player]を定義 void Start () { Debug.Log(player.name); // [player]のGameObject名表示 } } |
このスクリプトでは、
“player”というGameObjectを定義しているが、初期化が行われずに使用されています。
[原因]
スクリプトで定義したGameObjectを、初期化することなく使用した。
[対策]
Find関数を使ってシーン内(Hierarchy)からGameObjectを取得したり、
Prefabを使ってGameObjectを生成するなどして、
しっかりと初期化を行ってください。
こちらが、Find関数を使った正しいスクリプトになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using UnityEngine; public class Example : MonoBehaviour { private GameObject player; // GameObject"player"を定義 void Start () { player = GameObject.Find("player"); // Scene内の"player(GameObject)"を取得 Debug.Log(player.name); // "player"のGameObject名表示 } } |
続いては、
上記のようにFind関数を使って、しっかりと初期化したにもかかわらず、
NullReferenceExceptionのエラーが出る場合です。
Find関数でGameObjectの取得に失敗している
スクリプトには問題ないが、NullReferenceExceptionのエラーが出る場合があります。
これはFind関数を使ってGameObjectを取得している場合に発生して、
原因は2つあります。
[原因1]
そもそも指定したGameObjectがScene内に存在していない。
存在していないのだから取得できなくて当然ですよね。
もちろん、指定したGameObject名のスペルミスの場合も同様です。
[対策]
Scene内(Hierarchy)にGameObjectが間違いなく存在していること、
指定したGameObject名に間違いがないことを確認してください。
[原因2]
Find関数で取得するGameObjectが非アクティブになっている。(画像2)
見落としがちですが、
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のエラーと対策の解説を終わります。