見出し画像

UnityでConsoleを活用する方法|よく使う機能と実行中エラーの対処法

Unityでゲームを作っていると、

「再生したら赤いエラーが出た」
「ボタンを押しても反応しない」
「オブジェクトが動かない」
「どこまで処理が動いているのか分からない」

ということがよくあります。

そんなときに確認するのが Consoleウィンドウ です。

前回は、Debug.Log、Debug.LogWarning、Debug.LogError、Debug.DrawLine、Debug.DrawRay について説明しました。

今回は、その続きとして、Consoleウィンドウでよく使う機能と、ゲームを再生したあとに出やすいエラーの意味・対処法について説明します。



今回扱うエラーについて

Unityのエラーには、大きく分けて次の2種類があります。

・再生前に出るエラー
・再生中に出るエラー

例えば、

; expected(; が足りない)
} expected(} が足りない)
CS0103(変数名・関数名が見つからない)

のようなエラーは、スクリプトの書き方に問題があり、再生前に出ることが多いエラーです。

今回はそれらではなく、ゲームを再生したあとに出るエラー を中心に扱います。

具体的には、以下のもの

・NullReferenceException
・UnassignedReferenceException
・MissingComponentException
・IndexOutOfRangeException
・MissingReferenceException


Consoleでよく使う機能

Consoleにはいろいろな機能がありますが、初心者のうちは、まず次の機能を覚えておくと便利です。


Clear

Clear は、Consoleに表示されているログやエラーを消す機能です。

何度もゲームを再生していると、古いログやエラーが残って、今の実行結果が分かりにくくなることがあります。
そのようなときは、Clearを押してConsoleを整理します。

初めのうちは、エラーを直したつもりでも、Consoleに古いエラーが残っていて混乱することがあります。
まずClearで消してから、もう一度再生して確認するのがおすすめです。

また「Clear on Play」にチェックを入れておくと、Playの前に自動でエラーがクリアされます。


Collapse

Collapse は、同じ内容のログをまとめて表示する機能です。

例えば、Update の中に Debug.Log を書くと、毎フレーム同じログが表示されます。

void Update()
{
    Debug.Log("Updateが呼ばれています");
}

このようなコードを書くと、Consoleに同じログが大量に表示されます。

Collapseをオンにすると、同じ内容のログがまとめて表示されるため、Consoleが見やすくなります。

ただし、ログが何回出たのか、1回ずつ流れを細かく見たい場合は、Collapseをオフにした方が分かりやすいこともあります。

同じログが多すぎる
→ Collapseをオン

ログの流れを1つずつ見たい
→ Collapseをオフ

というように使い分けると便利です。


Error Pause

Error Pause は、エラーが出た瞬間にゲームの再生を一時停止する機能です。

エラーが出ていることは分かっても、「どのタイミングでエラーが出たのか分からない」ということがあります。
そんなときにError Pauseをオンにしておくと、エラーが発生した瞬間にUnityが一時停止します。

例えば、

・敵にぶつかった瞬間にエラーが出る
・アイテムを取った瞬間にエラーが出る
・ステージを切り替えた瞬間にエラーが出る

という場合、どのタイミングで問題が起きているのかを確認しやすくなります。
ただし、エラーが何度も発生する状態だと、そのたびに再生が止まってしまいます。
そのため、普段から常にオンにするというより、原因を調べたいときにオンにする使い方がおすすめです。


Show Timestamp

Console右上のメニューから Show Timestamp をオンにすると、ログが表示された時刻を確認できます。

ログが少ない場合はあまり気にしなくてもよいですが、処理の順番を確認したいときに便利です。

例えば、

Debug.Log("ゲーム開始");
Debug.Log("敵を生成");
Debug.Log("ステージ読み込み完了");

のように複数のログを出している場合、どの順番で処理が行われたのかを確認できます。
時間差で動く処理や、コルーチンを使った処理を確認するときにも役立ちます。


Open Editor Log

Open Editor Log は、Unityエディター側の詳しいログを開く機能です。

通常の学習では、Consoleに表示される内容だけで十分なことが多いです。ただし、

・Unityエディター自体の動作を確認したい
・パッケージ関連の問題を調べたい
・ビルド時の詳しいログを確認したい

という場合に使うことがあります。


Open Player Log

Open Player Log は、ビルドしたゲーム側のログを開く機能です。

Unityエディター上では問題なく動いているのに、ビルドしたアプリでだけ動かないことがあります。
例えば、次のようなケースです。

・Windows用にビルドしたゲームでエラーが出る
・Android実機でだけ動かない
・Unity上では動くのに、アプリにすると動かない

このようなときに、ビルドしたゲーム側のログを確認するために使います。

最初のうちは使う機会は少ないかもしれませんが、実機確認やアプリ公開をするようになると大切になる機能です。


Stack Trace Logging

Stack Trace Logging は、ログやエラーがどこから呼ばれたのかを表示する設定です。

エラーが出たとき、Consoleにはスクリプト名や行番号が表示されます。
その情報をたどることで、

・どのスクリプトでエラーが起きたのか
・どの関数から呼ばれたのか
・どの処理の流れで問題が起きたのか

を確認できます。
初心者のうちは情報が多く感じるかもしれませんが、エラーの原因を探すときにとても重要な情報です。

基本的には、Consoleに表示されたエラーをダブルクリックして、該当するスクリプトを確認するところから始めるとよいです。


エラーが出たときの基本手順

エラーが出たときは、次の順番で確認しましょう。


1. Clearで古いログを消す

まず、Consoleに古いログやエラーが残っている場合は、Clearで消して、もう一度ゲームを再生します。
これにより、今の状態で出ているエラーだけを確認しやすくなります。


2. 一番上のエラーを見る

Consoleに複数のエラーが表示されている場合は、基本的に一番上のエラーから確認します。
1つの原因から、複数のエラーが連続して出ていることがあるためです。
最初のエラーを直すと、他のエラーも一緒に消えることがあります。


3. エラーをダブルクリックする

Consoleに表示されたエラーは、ダブルクリックすると、問題が起きているスクリプトを開くことができます。
多くの場合、Visual StudioやVisual Studio Codeが開き、該当する行が表示されます。
ただし、表示された行そのものだけが原因とは限りません。
その行の少し上や、Inspectorで設定しているオブジェクトが原因になっている場合もあります。


4. Debug.Logで途中の状態を確認する

どこまで処理が動いているのか分からないときは、Debug.Log を使って確認します。

void Start()
{
    Debug.Log("Startが呼ばれました");
}

ボタンを押したときに処理が呼ばれているか確認したい場合は、次のようにします。

public void OnClickButton()
{
    Debug.Log("ボタンが押されました");
}i

Consoleにログが表示されれば、その処理は実行されています。
表示されなければ、そもそも関数が呼ばれていない可能性があります。


よくある実行中エラー

1,NullReferenceException

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

これは、簡単に言うと「使おうとしたものが設定されていない」という意味です。
初めのころに特によく見るエラーの1つです。


[SerializeField] GameObject player;

void Start()
{
    player.SetActive(false);
}

このコードでは、player を非表示にしようとしています。
しかし、Inspectorで player に何も設定していないと、Unityは「どのオブジェクトを非表示にすればいいの?」という状態になります。

その結果、NullReferenceException が表示されます。


対処法

まず、Inspectorを確認します。
[SerializeField]public で表示されている項目に、必要なオブジェクトが入っているか確認しましょう。

GetComponentGameObject.Find で取得している場合は、取得できているかを確認します。

Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();

    Debug.Log(rb);
}

Consoleに null と表示される場合は、取得できていません。
その場合は、対象のオブジェクトに必要なコンポーネントが付いているか確認します。

対象のオブジェクトを探しに行く方法は、こちらでご確認ください。


2,UnassignedReferenceException

UnassignedReferenceException

これは、Inspectorで設定するはずの変数に、何も設定されていないときに出るエラーです。
NullReferenceException と似ていますが、Unityでは特にInspector上の参照が空のときに表示されることがあります。


[SerializeField] GameObject bulletPrefab;

void Start()
{
    Instantiate(bulletPrefab);
}

このコードでは、bulletPrefab を生成しようとしています。
しかし、Inspectorで bulletPrefab にプレハブを入れていないと、再生時にエラーになります。


対処法

Inspectorで、対象の項目に必要なPrefabやオブジェクトが入っているか確認します。

スクリプトを付けたオブジェクトを選択
↓
Inspectorを見る
↓
空欄になっている項目がないか確認
↓
必要なPrefabやオブジェクトをドラッグして設定

特に、Prefabを生成する処理では、このエラーがよく起こります。


3,MissingComponentException

MissingComponentException

これは、必要なコンポーネントが付いていないときに出るエラーです。


Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();
    rb.AddForce(Vector3.up * 5f);
}

このコードでは、同じオブジェクトに付いている Rigidbody を取得して、上方向に力を加えようとしています。

しかし、スクリプトを付けたオブジェクトに Rigidbody が付いていないと、正しく処理できません。

Unityでは、次のようなメッセージが表示されることがあります。

MissingComponentException: There is no 'Rigidbody' attached to the "Player" game object

対処法

対象のオブジェクトに、必要なコンポーネントが付いているか確認します。

PlayerにRigidbodyが必要
↓
Playerを選択
↓
Inspectorを確認
↓
Rigidbodyがなければ追加

また、2Dゲームの場合は Rigidbody ではなく Rigidbody2D が必要な場合があります。

Rigidbody2D rb;

3D用と2D用のコンポーネントを間違えないように注意しましょう。


4,IndexOutOfRangeException

IndexOutOfRangeException: Index was outside the bounds of the array.

これは「配列の範囲外を指定しています」という意味です。


int[] scores = { 10, 20, 30 };

Debug.Log(scores[3]);

配列は0番目から数えます。
この場合、配列の中身は次のようになります。

scores[0] → 10
scores[1] → 20
scores[2] → 30

scores[3] は存在しません。
そのため、IndexOutOfRangeException が表示されます。


対処法

配列の数を確認します。

Debug.Log(scores.Length);

配列の場合は Length を使います。
リストの場合は Count を使います。

Debug.Log(itemList.Count);

また、繰り返し処理で配列を使う場合は、範囲を超えていないか確認しましょう。

for (int i = 0; i < scores.Length; i++) //これはOK!
{
    Debug.Log(scores[i]);
}
for (int i = 0; i <= scores.Length; i++) //これはNG!
{
    Debug.Log(scores[i]);
}

i <= scores.Length のように書いてしまうと、最後に範囲外を指定してしまうので注意が必要です。


5,MissingReferenceException

MissingReferenceException

これは「すでに削除されたオブジェクトを使おうとしています」という意味です。


Destroy(enemy);

enemy.SetActive(false);

このコードでは、enemy を削除したあとに、さらに enemy.SetActive(false) を実行しようとしています。

すでに削除されたオブジェクトを使おうとすると、MissingReferenceException が出ることがあります。


対処法

Destroy したオブジェクトを、その後も使っていないか確認します。
必要な処理がある場合は、削除する前に行います。

enemy.SetActive(false);
Destroy(enemy);

ただし、オブジェクトを本当に削除する必要があるのかも考えましょう。
一時的に非表示にしたいだけなら、Destroy ではなく SetActive(false) の方がよい場合もあります。

enemy.SetActive(false);

敵や弾を何度も使い回すゲームでは、削除ではなく非表示にして再利用する方法もよく使われます。


6,ArgumentExceptionについて

ゲーム制作では、ArgumentException が出ることもあります。
これは、指定した名前や値が正しくないときに出ることがあります。

例えば、

・SceneManagerで読み込むシーン名が間違っている
・Animatorのパラメーター名が間違っている
・存在しない名前を文字列で指定している

といった場合です。


SceneManager.LoadScene("GameScene");

このとき、GameScene というシーン名が間違っていたり、Build Profilesに登録されていなかったりすると、エラーになることがあります。

また、Animatorの場合も、スクリプト側の名前とAnimator側の名前が一致していないと問題になります。

animator.SetBool("IsRuning", true);

Animator側では IsRunning なのに、スクリプト側で IsRuning と書いているようなケースです。


対処法

文字列で名前を指定している部分を確認します。

シーン名は正しいか
Build Profilesに登録されているか
Animatorのパラメーター名は一致しているか
大文字・小文字は合っているか
スペルミスはないか

文字列で指定するものは、少しの違いでも別の名前として扱われます。

特に、大文字・小文字の違いや、スペルミスには注意しましょう。


Debug.Logで原因を探す例

エラーの原因が分からないときは、Debug.Log を使って、処理の途中を確認します。

オブジェクトが取得できているかを確認

例えば、プレイヤーを取得できているか確認したい場合は、次のようにします。

[SerializeField] GameObject player;

void Start()
{
    Debug.Log(player);
}

Consoleにオブジェクト名が表示されれば、参照できています。
null と表示された場合は、何も設定されていません。


処理が呼ばれているか確認する

ボタンや当たり判定が反応しているか分からない場合も、Debug.Log が便利です。

void OnTriggerEnter(Collider other)
{
    Debug.Log("何かに触れました");
}

Consoleに表示されれば、OnTriggerEnter は呼ばれています。
表示されなければ、そもそも当たり判定が発生していない可能性があります。

その場合は、

・Colliderが付いているか
・Is Triggerの設定は正しいか
・Rigidbodyが必要なオブジェクトに付いているか
・Layerの設定で衝突しないようになっていないか

などを確認します。


変数の中身を確認する

変数の値が思った通りになっているか確認したい場合も、Debug.Log を使います。

int hp = 100;

void Start()
{
    Debug.Log("HP:" + hp);
}

文字と変数をつなげて表示すると、Consoleで確認しやすくなります。

Debug.Log("現在のスコア:" + score);
Debug.Log("プレイヤーの位置:" + transform.position);
Debug.Log("ジャンプ中:" + isJumping);

このように、処理の途中で値を確認することで、どこで想定と違う動きになっているのかを探しやすくなります。


まとめ

今回は、UnityのConsoleでよく使う機能と、ゲームを再生したあとに出やすいエラーについて説明しました。

Consoleでは、次の機能をよく使います。

Clear
→ 古いログを消す

Collapse
→ 同じログをまとめる

Error Pause
→ エラーが出た瞬間に止める

Show Timestamp
→ ログが出た時刻を表示する

Open Editor Log
→ Unityエディター側の詳しいログを見る

Open Player Log
→ ビルドしたゲーム側のログを見る

エラーが出たときは、まず次の順番で確認しましょう。

Clearで古いログを消す
↓
もう一度再生する
↓
一番上のエラーを見る
↓
エラーをダブルクリックする
↓
該当する行と、その周辺を見る
↓
Inspectorの設定を確認する
↓
Debug.Logで途中の状態を確認する

ゲーム制作では、エラーは必ず出てきます。
大切なのは、エラーを怖がることではなく、Consoleを使って原因を少しずつ探していくことです。

最初は英語のエラーが難しく見えるかもしれませんが、よく出るエラーの意味を少しずつ覚えていけば、原因を見つけやすくなります。

ConsoleとDebug.Logをうまく使いながら、エラーを1つずつ解決していきましょう。


こちらはUnity初心者向けの記事をテーマ別にまとめています。

▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。

ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!