Version: 2023.2
言語: 日本語
UnityEvent
Await support

Null Reference Exception

どのオブジェクトにも参照を持たない参照変数にアクセスしようとすると、NullReferenceException (Null リファレンスの例外) が起こります。参照変数がオブジェクトを参照していない場合、それは null として扱われるでしょう。実行して変数がnullのとき,『NullReferenceException』を出すことによってオブジェクトにアクセスしようとしていることを教えてくれます。

C# と JavaScript の参照変数は、C と C++ のポインタの概念と似ています。どのオブジェクトも参照していないことを示すために、参照型は null がデフォルトです。そして、参照されているオブジェクトにアクセスして、なければ、NullReferenceException を返します。

コードで NullReferenceException を返した場合は、使用する前に変数の設定をしていないことを意味します。エラーメッセージは、以下のようになります。

NullReferenceException: Object reference not set to an instance of an object
  at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10

このエラーメッセージには、スクリプトファイル Example.cs の10行目で NullReferenceException が起こったということです。また、メッセージは、例外が Start() 関数の内部で起きたと言っています。これで Null Reference Exception を見つけて修正することが容易になります。この例では、コードは以下のとおりです。

//c# example
using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

    // イニシャライゼ―ションに使用します
    void Start () {
        GameObject go = GameObject.Find("wibble");
        Debug.Log(go.name);
    }

}

コードは、単に “wibble” と呼ばれるゲームオブジェクトを探します。この例では、“wibble”という名前のゲームオブジェクトがないので、Find() 関数は null を返します。次の行(10行目)で go 変数を使用してみて、それが参照するゲームオブジェクトの名前をログに出します。存在しないゲームオブジェクトにアクセスしているので、実行時に NullReferenceException が返されます。

Null チェック

上記のエラーが起きた場合、スクリプトをより厳密にする必要があります。解決策の例は次のとおりです。

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

    void Start () {
        GameObject go = GameObject.Find("wibble");
        if (go) {
            Debug.Log(go.name);
        } else {
            Debug.Log("No game object called wibble found");
        }
    }

}

そして、go 変数を使用する前に、null ではないことを確認してください。それが null なら、メッセージが表示されます。

Try/Catch ブロック

NullReferenceException が起きるもう一つの原因は、インスペクターで初期化する必要がある変数を初期化せずに使用した場合です。初期化を忘れた場合、その変数は null になります。NullReferenceException に対処するためのもう一つの方法は、try/catch ブロックを使用することです。たとえば、次のコードです。

using UnityEngine;
using System;
using System.Collections;

public class Example2 : MonoBehaviour {

    public Light myLight; // インスペクターで設定

    void Start () {
        try {
            myLight.color = Color.yellow;
        }       
        catch (NullReferenceException ex) {
            Debug.Log("myLight was not set in the inspector");
        }
    }

}

このコード例では、myLight という変数は、インスペクターウィンドウで設定する必要がある Light 型の変数です。この変数が初期化されていない場合、それは null がデフォルト値になります。try ブロック内で光の色を変更しようとすると、catch ブロックで拾われた NullReferenceException を引き起こします。catch ブロックは、アーティストやゲームデザイナーに、役立つかもしれないメッセージを表示して、インスペクターで光の設定をすることを促します。

要約

  • NullReferenceException は、スクリプトコードで設定されていない(参照されていない)変数やオブジェクトを使用したときに起こります。
  • 表示されるエラーメッセージは、問題が発生したコードの場所について伝えます。
  • オブジェクトにアクセスする前に null かどうかチェックするコードを書く、または、try/catch ブロックを使用することにより、NullReferenceException は避けることができます。
UnityEvent
Await support