UnityEvent
重要なクラス

Null Reference Exception とは何ですか?

どのオブジェクトにも参照していない参照変数にアクセスしようとすると、 NullReferenceException が起こります。参照変数がオブジェクトを参照していない場合、それは null として扱われるでしょう。変数が『NullReferenceException』を出すことによって null のとき、実行時、オブジェクトにアクセスしようとしていることを教えてくれます。

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 {

    // Use this for initialization
    void Start () {
        GameObject go = GameObject.Find("wibble");
        Debug.Log(go.name);
    }

}

コードは、単に “wibble” と呼ばれるゲームオブジェクトを探します。この例では、そこにその名前のゲームオブジェクトがないので、 Find() 関数は null を返します。次の行(9行目)で 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; // set in the inspector

    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
重要なクラス