NullReferenceExceptionを感覚で直さない

広告

― エラーを読む力は、コードを書く力と同じくらい重要 ―

UnityやC#の学習をしていると、多くの人が一度は遭遇するエラーがあります。それが NullReferenceException です。このエラーに何度もつまずいている人には、共通した「直し方の癖」があります。その癖を直すだけで、デバッグの速度と精度が大きく変わります。

NullReferenceException: Object reference not set to an instance of an object

このエラーを見ると、

  • 「またこれか…」
  • 「とりあえず AI に貼ろう」
  • 「SerializeField つければ直る?」
  • 「Inspectorで何か入れ忘れた?」

という反応になりがちです。ですが、ここで大事なのは 感覚で直さないこと です。原因を特定しないまま修正しても、同じエラーが別の場所で繰り返されるだけです。


NullReferenceExceptionとは何か

簡単に言うと、存在しないもの(null)を使おうとしたというエラーです。例えば:

GameObject enemy = null;
enemy.SetActive(false);

これは当然エラーになります。なぜなら enemy = null だからです。つまり、

  • オブジェクトが生成されていない
  • 参照が入っていない
  • 取得に失敗している

のに、それを使おうとしている。それが NullReferenceException です。


初学者がやりがちな危険な直し方

パターン1:とりあえず AI に投げる

エラー全文を貼って「直してください」と聞く。もちろん AI はかなり助けになります。でも問題は、なぜ null になったか理解しないまま修正することです。すると、

  • 今回は直る
  • 別の場所でまた起きる
  • また AI に聞く

というループになります。AI はあなたのプロジェクトの Scene 構造や Inspector 設定を知りません。最終的に原因を特定できるのは、コードを書いたあなた自身です。

パターン2:よく分からないままコードを足す

例えば:

if (enemy != null)
{
    enemy.SetActive(false);
}

一見、直ったように見えます。でも考えてみてください。なぜ enemy が null なのか? null チェックは「エラーを黙らせる」だけで、根本原因は何も解決していません。本来すべきことは、enemy がなぜ null になるのかを突き止め、正しく参照を取得することです。


エラーを読む順番

NullReferenceException が出たら、次の順番で調べてください。

1. Console を見る

Unity の Console には重要な情報が含まれています。例えば:

NullReferenceException
PlayerController.Update() (at Assets/Scripts/PlayerController.cs:42)

見るべきはここ。

  • クラス名(PlayerController)
  • メソッド名(Update)
  • 行番号(42行目)

2. 行番号を見る

42行目に何があるか確認します。例えば:

hpText.text = hp.ToString();

怪しいのはどちら? hpTexthp か。通常、値型の int hp は null になりません。なら怪しいのは hpText です。

3. null の候補を絞る

1行に複数のオブジェクトが連なっている場合もあります。

player.weapon.ammoText.text = ammo.ToString();

null 候補は playerweaponammoText と複数あります。だから感覚で直してはいけません。次のステップで一つずつ確認します。

4. Debug.Log で確認する

最もシンプルで確実な方法です。怪しい参照を一つずつ出力します。

Debug.Log(player);
Debug.Log(player.weapon);
Debug.Log(player.weapon.ammoText);

Console に Null と表示された行が、null になっているオブジェクトです。null チェックを当てずっぽうに書くより、まずここで原因を特定してください。

5. なぜ null になったか、自分の言葉で説明する

原因が分かったら、次の問いに自分自身で答えてみてください。

  • 何が null だった?
  • なぜ null だった?
  • いつ null になった?
  • どうすれば再発しない?

声に出して(あるいは頭の中で)説明できれば、本当に理解できた証拠です。ここまでできれば、かなり成長しています。


Unityで特によくある原因

1. Inspector未設定

[SerializeField]
private Rigidbody rb;

Inspectorでのアサイン忘れ。すると rb.velocity = ... で落ちます。[SerializeField] を書いただけでは参照は入りません。必ず Inspector 上で GameObject をドラッグしてセットしてください。

2. Find失敗

var obj = GameObject.Find("Player");

でも実際の GameObject 名が Player(Clone) だった場合、Find は失敗して null を返します。名前の一致は完全一致なので、Prefab から生成したオブジェクトは名前が変わっていることがあります。

3. Instantiate前に使っている

bullet.transform.position = spawnPos;  // ← まだ null
bullet = Instantiate(prefab);           // ← ここで生成

生成する前に使っています。順番を逆にするだけで直ります。

4. シーン遷移で消えた

UIManager.Instance.UpdateHp();

シーン切り替えで UI が破棄されたのに、Singleton の参照が残っている状態です。DontDestroyOnLoad の設計が不完全なときに起きやすいです。


AI時代だからこそ必要な力

生成AIはコードを書けます。でも、

  • Scene 構造
  • Inspector 設定
  • Prefab 参照
  • 実行タイミング

までは見えていません。AI はあなたのプロジェクト内部を完全には知らない。だから最終的に必要なのは、人間側の調査力です。AI を使うにしても、「原因はここだと思うが、どう直せばいい?」という聞き方ができるかどうかで、得られる答えの質が大きく変わります。


まとめ

NullReferenceException が出たら、感覚で直すのではなく、次の順番で調べましょう。

  1. Console を見る(クラス名・メソッド名・行番号を確認)
  2. 行番号を見る(その行の null 候補を特定)
  3. null 候補を絞る(複数ある場合は一つずつ)
  4. Debug.Log で確認する(Console に Null と出た箇所が原因)
  5. なぜ null か自分の言葉で説明できるか確認する

エラーが出ること自体は悪いことではありません。むしろ、エラーが出た時に、

  • パニックになる人
  • AIに丸投げする人
  • 原因を調査する人

で、成長速度が大きく変わります。プログラミングができる人とは、最初からエラーを出さない人ではありません。エラーを読んで、原因を切り分けて、修正できる人です。

NullReferenceException をただの「嫌なエラー」で終わらせず、デバッグ力を鍛える教材として使っていきましょう。

訪問数 10 回, 今日の訪問数 10回

広告

C#

Posted by hidepon