i-school - エラー発生時の問題点の切り分け手法1
 エラーの中でもよく目にする Null Reference Exceptions の対処方法について学習します。
Unity 公式マニュアル
Null Reference Exceptions



エラーの検証を行い、問題箇所を特定する

1.考え方


 エラーの発生している場所についてはエディターがヒントを提示してくれますが、
エラーの内容が理解できなければ、原因を特定することができないため、エラーを解消することが出来ません。

 そのため、問題点を切り分けて考えるという考え方が重要になります。


2.エラーの発生している行内の変数と型を調べる


 該当の Null Reference Exceptions エラーは、Unity の Console ビューに表示されます。
ダブルクリックすることでエディターのエラー箇所に移動しますので、その行でエラーが発生していることを、まずは理解します。

 Console ビューに表示されるエラーの表示方法には規則がありますので、まずはそちらを覚えましょう。
その上でスクリプトの何行目でエラーが出ているかを調べていくことになります。


3.変数を Null 状態になる型と Null にならない型とに分ける


 まずは問題点を切り分けていくため、エラーの発生している行内の変数を1つずつ確認します。
その上で、その変数の型が「参照型」に分類されるものか、「値型」に分類されるものかで分けていきます。

 値型は参照ではないので、Null にはならない型になります(Null 許容型として宣言している場合を除く)
そのため、まず変数の型の種類を分けることで、Null の状態が「発生する可能性のある型」であるのか、
発生しない型」であるのかを分けることにより、問題となる変数と問題のない変数とを切り分けていくことが出来ます。

 この手順において「値型」に分類される型の変数は、このエラーには該当しませんので、以後は調べる必要がありません
よって、この段階で「参照型」に分類される型の変数のみが Null エラーの候補として残ることになります。


4.戻り値の持つメソッドがあるか調べる


 次に、エラーの該当行内に変数の他にメソッドの実行命令があるとき、
そのメソッドが戻り値の持つメソッドであるか、戻り値の持たないメソッドであるかを調べる必要があります。
 
 戻り値の持たないメソッドの実行命令の場合には、それは Null エラーの候補にはならないメソッドの実行命令になりますので、
そのメソッドの実行命令部分は調べる候補から外れます。

 戻り値の持つメソッドの実行命令の場合には、それは Null エラーの候補になりますので、変数と合わせて調べていく必要があります


5.Null になる可能性のある変数や戻り値のあるメソッドの値を Debug.Log メソッドを利用して調べる


 【3】【4】の手順により、Null エラーに該当しそうな変数と戻り値のあるメソッドが見つかりましたので、これらを順番に調べていきます。

 調べていく場合、プログラムの行内の左側の変数やメソッドの実行命令から調べていきます。
なお、この時点で調べる変数が1つしか残っていない場合には、それが Null になっている変数、つまりエラーの原因になります。

 調べる変数が複数あったり、メソッドの実行命令がある場合、それらは順番に調べていく必要があります
プログラムの処理は左側から右側に向かって順番に処理されるため、エラー箇所を見つける場合もその順番、つまり、左側から順番に調べる方が適切です。

 これも問題点の切り分けていく手法の1つです。

 実際に変数の値を確認することで Null であるかを判断できますので、ここでは Debug.Log メソッドを活用します。

 Log メソッドは、エラーの発生している行よりも1行以上、上に処理を書くようにします。
なぜなら、エラーの発生している行よりも下に書いてしまうと、エラーで処理が停止してしまうため、Debug.Log メソッドが実行されないためです。

 この手法を使い、1つずつ、順番に変数や戻り値のあるメソッドの実行命令を Debug.Log メソッドを使い、調べていくことで、Null になっている変数を見つけることが出来ます。


問題箇所が特定できたら、解決方法を考える


 ここまでの手順により、エラーの原因となっている変数、あるいはメソッドの実行命令が特定出来ています。

 それぞれ修正の方法が異なりますので、修正方法を覚えておくようにしましょう。


1.変数の場合


 SerializeField属性 の付与された private 変数か、pulbic 変数である場合には、Unity のインスペクターを確認してください。
変数にクラスの情報がアサインされていない状態になっていますので、対象となるクラスがアタッチされているゲームオブジェクトを
ドラッグアンドドロップしてアサインすることでエラーが解消されます。

 private / protected 変数の場合には、スクリプト内の処理を見直し、変数に代入処理を行っている箇所を調べます。
代入処理自体がない場合には、新しく変数に代入する処理を追加します。

 すでに代入処理がある場合には、代入元になっている情報が Null の可能性も出てくるので、今度は、そちらも遡って調べる必要があります。
この際の調べ方は同じ手順です。

 このようにして処理を見直すことで、Null のエラーを解消します。


2.戻り値の持つメソッドの場合


 GetComponent メソッドの場合には、GetComponent メソッドの実行対象となるゲームオブジェクトに
GetComponent メソッドで取得しようとしているコンポーネントがアタッチされているかを確認してください。

 例えば、GetComponent<Text>() であれば、ゲームオブジェクトに Text コンポーネントがアタッチされているかを確認します。
アタッチされていなければ、Add Component を行って追加するなどして対応を行います。



 以上になります。

 Null エラーの発生する型の種類と、発生した場所の特定、そして解消方法、これらの手順を順番に行っていくことでエラーが解消出来ます。
Unity のインスペクターでのアサイン忘れ、あるいはプログラムに代入処理を書いていなかった場合などに発生するエラーになりますので、
何回かエラーを直していくことで、原因と対処方法を学習することが出来ます。

 エラーが表示されることは問題ではなく、何が原因なのか、どうすれば解消できるのか、次からは何を気を付ければいいのか、
そういった部分をしっかりと学習していくことが、今後のプログラムのスキルの向上につながります。