ドキュメント

Unity Engine

Unity Engine

Null 参照

Understand what causes a NullReferenceException in C# and how to avoid uninitialized object references.
読み終わるまでの所要時間 6 分最終更新 1ヶ月前

C# で値が
null
型のメンバーにアクセスしようとすると、
NullReferenceException
が発生します。ランタイムの
NullReferenceException
は、多くの場合、オブジェクトリファレンス変数を、使用する前に初期化しなかったことを意味します。null 参照が発生する一般的なコーディングエラーの詳細については、Microsoft のドキュメントを参照してください。
null 参照のエラーメッセージは次のようになります。
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 の検出と修正が容易になります。この例では以下のようなコードになります。
using UnityEngine;using System.Collections;public class Example : MonoBehaviour { // Use this for initialization void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); Debug.Log(myGameObject.name); } }
コードは "exampleGameObject" というゲームオブジェクトを探します。この例では、同じ名前のゲームオブジェクトがないので、
Find()
関数は
null
を返します。スクリプトは次の行 (9 行目) で
myGameObject
変数を使用し、参照するゲームオブジェクトの名前を出力します。存在しないゲームオブジェクトにアクセスしようとしているため、
NullReferenceException
が返されます。

Null checks

この例でのソリューションは、指定された名前のゲームオブジェクトが存在しない場合の結果を追加することです。以下のスクリプトは、
go
変数が
null
を返すかどうかを確認し、返す場合はメッセージを表示します。
using UnityEngine;using System.Collections;public class Example : MonoBehaviour { void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); if (myGameObject == null) { Debug.Log("No GameObject called exampleGameObject found"); } else { Debug.Log(myGameObject.name); } } }

カスタムの == 演算子

UnityEngine.Object から継承する型の場合、Unity では C# の等式演算子および不等式のカスタム版が使用されます。つまり、前の例 (
myGameObject == null
) の null チェックは、技術的には
myGameObject
が有効な C# オブジェクトリファレンスを保持していても、
true
を評価できます (また、逆に
myGameObject != null
は
false
を評価できます)。これは 2 つのケースで発生します。
  1. オブジェクトが、いわゆる "fake null" またはプレースホルダーオブジェクトの場合。これは、Unity では初期化されていない MonoBehaviour フィールドに入力するためにのみ、エディターで使用されます。これらのオブジェクトは、フィールドをリファレンスしようとしたときに、そのソースを見つけるために役立つデバッグ情報を格納します。
  2. オブジェクトが、まだガベージコレクションされていないマネージ (C#) オブジェクトである可能性があるものの、アンマネージ (C++) のオブジェクトが破棄されているために、null と見なす必要がある場合。

Try/Catch ブロック

Inspector ウィンドウで初期化が必要な変数を使用する場合も、
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
で、Inspector ウィンドウで設定する必要があります。この変数が設定されていない場合は、デフォルトで
null
になります。
try
ブロックのライトの色を変更しようとすると、
NullReferenceException
が発生します。この場合、
catch
ブロックコードによって、Inspector でライトを設定するように促すメッセージが表示されます。

追加リソース