こんにちは!かとこうです。
Unityでゲームを作っていると、
突然こんな赤い文字が出てきて
ビックリすることがありませんか?
NullReferenceException: Object reference not set to an instance of an object
僕もUnityを始めたばかりの頃、
このエラーが出るたびに
「え、何これ・・・何が悪いの?」
と画面の前で固まっていました。
でも安心してください。
このエラーは、Unity初心者なら
ほぼ全員が通る道なんです。
そして、原因がわかってしまえば
意外とシンプルに解決できます。
この記事では、
NullReferenceExceptionが出る原因と
その解決法を、できるだけわかりやすく
解説していきますね。
そもそもNullReferenceExceptionって何?
まず、このエラーが何を
言っているのかを理解しましょう。
ざっくり言うと、
「使おうとしたものが、まだ準備できていないよ!」
というエラーです。
現実の世界で例えてみると・・・
たとえば、あなたが友達に
電話をかけようとしたとします。
でも、スマホの連絡先に
その友達の番号が登録されていなかったら、
電話をかけることはできないですよね。
NullReferenceExceptionも
これと同じようなイメージです。
プログラムの中で
「この相手に連絡して!」と指示を出したけど、
連絡先(データ)がまだ入っていない
という状態だったので、
「連絡先が見つからないよ!」
とUnityが教えてくれている、
というわけなんです。
プログラミングの世界では、
この「まだ何も入っていない状態」のことを
Null(ヌル) と呼びます。
つまりNullReferenceExceptionは、
「Nullのものを使おうとしたよ」
というエラーなんですね。
NullReferenceExceptionが出る主な原因
では、実際にどんな時に
このエラーが出るのかを見ていきましょう。
初心者の方がつまずきやすい
代表的なパターンを3つ紹介しますね。
原因①:インスペクターでの設定忘れ
これが一番多い原因です。
スクリプトの中で
public GameObject enemy;
のように変数を作ったとします。
この変数は、いわば
「名前だけ書いた空っぽの箱」 です。
箱の中に実際のオブジェクトを
入れてあげないと、使うことができません。
この「箱に中身を入れる作業」が、
Unityのインスペクターでの
ドラッグ&ドロップによる設定なんです。
ここを忘れてしまうと、
プログラムが「箱の中身を使って!」と
指示を出した時に、
「箱の中、空っぽなんだけど…!」
とエラーが出てしまうわけですね。
解決法
Unityエディタに戻って、
スクリプトがアタッチされている
ゲームオブジェクトを選択し、
インスペクターを確認してみてください。
変数の欄が「None」になっていたら、
そこに対応するオブジェクトを
ドラッグ&ドロップで設定しましょう。
原因②:GetComponentで取得できていない
スクリプトの中で、
Rigidbody rb = GetComponent<Rigidbody>();
と書いて、コンポーネントを
取得しようとすることがありますよね。
でも、このスクリプトがついている
ゲームオブジェクトに
Rigidbodyが追加されていなかったら、
取得するものがないので
変数の中身はNullになってしまいます。
これも現実で例えると、
「冷蔵庫からジュースを取ってきて」
と頼まれたのに、
冷蔵庫の中にジュースが入っていない、
という状態に似ていますね。
解決法
GetComponentで取得しようとしている
コンポーネントが、ちゃんとゲーム
オブジェクトに追加されているか
確認しましょう。
対象のゲームオブジェクトを選択して、
インスペクターを見てみてください。
もし追加されていなかったら、
「Add Component」ボタンから
追加してあげればOKです。
原因③:Findで見つからない
GameObject player = GameObject.Find("Player");
このコードは、シーンの中から
「Player」という名前のオブジェクトを
探してくる処理です。
ただし、名前が一文字でも
違っていると見つけることができません。
たとえば、
・ 「Player」と「player」(大文字・小文字の違い)
・ 「Player」と「Player 」(後ろにスペースが入っている)
こういった小さな違いでも
Nullになってしまうんです。
これは、宅配便の届け先の住所が
一文字だけ間違っていると届かない、
というのと同じですね。
解決法
ヒエラルキーでオブジェクトの名前を確認して、
スクリプトに書いた名前と
完全に一致しているかチェックしましょう。
コピー&ペーストで名前を
スクリプトに貼り付けると、
打ち間違いを防げるのでおすすめです。
エラーが出た時の調べ方
ここまで主な原因を紹介してきましたが、
「自分のエラーがどれに当てはまるかわからない・・・」
という方もいると思います。
そんな時に使える、
エラーの原因を見つけるための
方法をお伝えしますね。
コンソールのエラーメッセージを読んでみよう
Unityの画面下にある
コンソールウィンドウに表示される
エラーメッセージには、
実は大事な情報が書かれています。
たとえば、
NullReferenceException: Object reference not set to an instance of an object
PlayerController.Update () (at Assets/Scripts/PlayerController.cs:15)
この場合、
・ 「PlayerController」→ エラーが起きたスクリプトの名前
・ 「Update」→ エラーが起きた処理(メソッド)の名前
・ 「:15」→ エラーが起きた行番号
ということがわかります。
つまり、「PlayerController.cs」という
スクリプトの15行目あたりに
原因がありそうだ、ということなんですね。
コンソールのエラーメッセージを
ダブルクリックすると、
該当するスクリプトの行まで
自動で飛んでくれるので、
ぜひ活用してみてください。
Debug.Logを使って確認する方法
もう一つ便利な方法として、
Debug.Logを使ったやり方があります。
エラーが出ている行の手前に、
Debug.Log(enemy);
のように書いてみてください。
ゲームを再生すると、
コンソールにその変数の中身が
表示されます。
ここで「Null」と表示されたら、
その変数に中身が入っていないことが
確認できるので、
「この変数が原因だな」と
特定することができます。
エラーが出ても焦らないで大丈夫
NullReferenceExceptionは、
Unityを使っていると
何度も何度も出会うエラーです。
僕自身、今でもたまに出ますし、
最初の頃は本当によく出ていました。
でも、だんだん慣れてくると
「あ、多分あそこの設定を
忘れてるんだな」
とすぐにピンとくるように
なってくるんですよね。
なので、このエラーが出た時は
焦らずに、
1. コンソールでエラーの場所を確認する
2. その行で使っている変数が空っぽ(Null)になっていないか調べる
3. インスペクターやヒエラルキーで設定を見直す
この3つのステップで
落ち着いて確認してみてください。
きっと解決できるはずです。
エラーは怖いものではなくて、
Unityが「ここを直すといいよ」と
教えてくれているサインなので、
一つずつ解決しながら、
一緒にゲーム制作を
楽しんでいきましょう!
最後まで読んでいただきありがとうございました。