
Unityのデバッグクラスを使用してQAとデバッグプロセスを改善する方法を学びましょう。
Debug.Log関数にすでに慣れているかもしれませんが、Unityのデバッグクラスは、テストとデバッグを迅速化するのに役立つ多くの便利な関数をサポートしています。このページでは、シーンとゲームビューでのギズモの可視化のためのデバッグクラスの使用方法、スクリプトからエディタでの再生モードを一時停止する方法、その他のヒントについて説明します。
Unityに慣れているなら、エディタによって生成されたエラー、警告、その他のメッセージを表示するためにコンソールウィンドウを使用したことがあるでしょう。また、Debugクラスを使用して自分のメッセージをコンソールに印刷したこともあるでしょう。
しかし、Debug.Logメッセージだけに制限されるわけではありません。コンソールウィンドウに出力する文字列を作成する際には、エラー、警告、メッセージの3種類のいずれかを指定でき、それぞれに独自のアイコンタイプがあります。
3つのバリアントは:
コンソールウィンドウを使用して、メッセージを好みに基づいてフィルタリングできます。コンソールウィンドウでエラーポーズを有効にすることで、Debugクラスを介してコンソールに書き込むエラーがUnityの再生モードを一時停止させることができます。
Unityまたは自分のメッセージによってコンソールウィンドウに出力されたすべての内容は、アプリケーション内で問題が発生した場所を確認するために参照できるログファイルに追加されます。各オペレーティングシステムはログファイルを異なる場所に保存するため、各システムの仕様を確認するにはドキュメントをチェックしてください。

エラーまたは例外が発生すると、コンソールウィンドウはエラーメッセージとともにスタックトレースを表示し、エラーがどのように発生したか、どこから発生したかを理解するのに役立ちます。Debug.Logはコンソールにメッセージを送信することを可能にしますが、スタックトレースに表示される詳細レベルを構成することもできます。
デフォルトでは、コンソールの出力はメッセージを生成したコードの行にリンクされており、エントリが表示される原因となった行、メソッド、または関数呼び出しのシーケンスを特定しやすくなっています。
スクリプトが選択したIDEで開かない場合は、ファイル > 設定 > 外部ツールに移動し、ドロップダウンから「外部スクリプトエディタ」を選択してください。
エディタ内のファイル > ビルド設定… > プレイヤー設定… > その他の設定を介して、スタックトレースに表示される情報を構成できます。
各ログタイプに利用可能なオプションは次のとおりです:
ログが混雑した場合は、コンソールの検索機能を利用してください。検索語を入力すると、コンソールは一致するテキストを含むメッセージのみを表示するようにフィルタリングします。
コンソールメニューボタンをクリックし、メニューからログエントリ > [X] 行を選択することで、リスト内の各エントリに表示される行数を制御できます。[X]は各エントリに表示する行数です。
C#のString.Formatメソッドを使用すると、埋め込まれたフォーマットされた変数データを持つ文字列を作成できます。DebugクラスにはDebug.LogFormatがあり、同じ構文を使用します。
最初のパラメーターはフォーマットされたメッセージ文字列です。波括弧内にインデックス値を含めることで、これはパラメーターインデックス-1によって置き換えられます。存在する場合はそのToStringメソッドを使用するか、Systemの文字列変換が使用されます。上記のコード例では、14行目で{0}はorigin.ToString()に置き換えられます。
より複雑な例はこれです:
Debug.LogFormat("開始時のtransform.position={0}, transform.rotation={1}", transform.position, transform.rotation);
{0}はパラメーター1、transform.positionに置き換えられ、{1}はパラメーター2、transform.rotationに置き換えられます。各ケースでVector3およびQuaternionプロパティのToStringメソッドが使用されます。結果は次のようになります:
“原点は(0.00, 0.00, 0.00)
UnityEngine.Debug:LogFormat (string,object[])”
これらのログメソッドにオプションの2番目のパラメーターを提供して、メッセージが特定のGameObjectに関連付けられていることを示すこともできます:
Debug.LogWarning("私は平和に来ました!", this.gameObject);
フォーマットされた変数データを表示する際には、Debug.LogFormatの警告およびエラー版があります:
Debug.Logformat を使用して Console に float 値を送信すると、デフォルトのディスプレイには小数点以下6桁の数字が表示されます。この動作はカスタム数値フォーマット文字列で制御できます。
Debug.LogFormat("π = {0:0.00}", Mathf.PI);
コロンを使用することで、フォーマット文字列 0.00 は値の整数部分、小数点区切り、区切りの後の2桁の数字を表示します。最後の数字は、次の値に基づいて、4は切り捨て、5は切り上げるというおなじみの方法で丸められます。
この例では、出力は次のようになります: π = 3.14
Debug.Assert() は Debug.Log() メソッドに似ていますが、コンソールにメッセージをログする代わりに、条件をテストし、条件が偽の場合はエラーメッセージを表示します。これは、仮定を検証し、開発中にエラーをキャッチするために使用されます。
アサーションは、プログラムが予期しない状態に入らないことを確認するための素晴らしい方法です。これは、if ステートメント内に Log を埋め込むようなものです。クラスプロパティが割り当てられていることに依存するメソッドに取り組んでいるとき、アサーションはエラーを追跡するのに役立ちます。
Debug.Assert() が呼び出されると、テストする条件と、条件が偽の場合に表示する任意のメッセージの2つのパラメータを取ります。条件が真の場合、何も起こらず、プログラムは実行を続けます。条件が偽の場合、プログラムの実行が停止し、エディタにエラーメッセージが表示されます。
void SetColor(Color color)
{
Debug.Assert(material != null, "ChangeColor: material が割り当てられていません");
material.SetColor("_Color", color);
}
SetColor を呼び出し、material が割り当てられていない場合、‘SetColor: material が割り当てられていません’ がコンソールに表示されます。
Debug.Break() は、Unity の Debug クラスによって提供されるメソッドで、ゲームの実行を一時停止し、コードの現在のポイントでデバッガに入るために使用されます。ゲームの状態を検査し、コードを行ごとにステップ実行してバグを見つけて修正することができます。
Debug.Break()が呼び出されると、ゲームの実行が停止し、デバッガウィンドウが開きます。これにより、ゲームの状態を調べ、必要に応じてコードをデバッグできます。デバッガを使用してコードをステップ実行し、ブレークポイントを設定し、メモリ内の変数やオブジェクトを検査できます。
例えば、NPCがプレイヤーキャラクターのターゲット距離内にいるときにゲームを停止したいかもしれません。ゲームが中断されると、Inspectorでその状態を調べることができます:
float dist = Vector3.Distance(transform.position, npc.position);
if ( dist < 5) Debug.Break();

Debug.DrawLineとDebug.DrawRayは、UnityのDebugクラスによって提供される視覚デバッグ用の2つのメソッドです。これらは、衝突やレイキャストなどの物理関連のコードをテストおよび視覚化するのに役立ちます。どちらも、ゲームビューとシーンビューの両方で表示される色付きの線を描画できます。例えば、Debug.DrawRayを使用して弾丸の軌道やレーザービームの経路を視覚化し、Debug.DrawLineを使用してコライダーの境界やオブジェクトの動きを視覚化できます。
Debug.DrawLineは、シーン内の2つの点の間に直線を描画するために使用されます:
Debug.DrawLine(transform.position, target.position, Color.white, 0, false);
開始点、終了点、および任意の色を含む2から5のパラメータを取ります。例えば、次のコードは、startとendのポイントの間に白い線を描画します:
public static void DrawLine(Vector3 start, Vector3 end, Color color = Color.white, float duration = 0.0f, bool depthTest = true);
パラメータ
コード例では、Skeleton GameObjectにアタッチされたMonoBehaviourスクリプトのUpdateメソッドが上記の画像を生成します。ラインは、ギズモが有効になっている場合にのみゲームビューで表示されます。ゲームビューのペインの右上にあるギズモボタンをクリックして有効にします。ラインはシーンビューでも表示されます。
DrawLineの代替はDrawRayです。Debug.DrawRayは、指定された原点から始まり、指定された方向に延びるレイをシーンに描画するために使用されます。デフォルトでは、それは無限のレイです。Debug.DrawRay()によって描かれたレイがコライダーに当たると、交差点で停止し、それ以上は続きません。この動作は、シーン内のオブジェクト間の衝突を検出するために使用されるUnityのレイキャストと同じです。
ここで、2番目のパラメーターは線の方向と長さを定義します。線は開始から開始 + dirまで描画されます:
public static void DrawRay(Vector3 開始, Vector3 dir, Color color = Color.white, float 継続時間 = 0.0f, bool depthTest = true);
コード例のパラメーターは次のとおりです:
別のコード例は次のとおりです:
Vector3 dir = transform.TransformDirection(Vector3.forward) * 3;Debug.DrawRay(transform.position, dir, Color.white, 0, false);
このコード例では、Skeleton ゲームオブジェクトに添付された MonoBehaviour スクリプトの Update メソッドが上の画像を生成します。長さを持つレイは、近接テストのデバッグに役立ちます。ここでは、レイの長さは3ワールドユニットです。攻撃が3ユニットで開始される場合、シーン内で3ユニットがどれくらいの長さかを視覚的にテストできます。

ギズモは、Unityでの視覚的デバッグのための強力なツールです。それらを使用すると、シーンビューでシンプルな2Dおよび3Dの形状、線、テキストを描画でき、ゲームワールドで何が起こっているかを簡単に見ることができます。
数行のコードでシーンビューにシンプルな形状や線を描画できます。これにより、ゲームメカニクスを迅速にプロトタイピングおよびテストするための理想的なツールになります。それらはリアルタイムで描画されるため、コードの変更の結果をすぐに見ることができ、必要な変更を加えることができます。
ギズモは、コードだけでは理解が難しい複雑なゲームメカニクスを視覚的に示します。例えば、ギズモを使用して、弾道の経路を示す線を描画したり、上の画像に見られるようにトリガーゾーンの境界を視覚化したりできます。
ギズモを使用して、他のチームメンバーがあなたのコードやゲームメカニクスを理解しやすくするための視覚的な補助を作成します。
ギズモはパフォーマンスにほとんど影響を与えないため、パフォーマンスを低下させることなく自由に使用できます。
ギズモアイコンは、シーンビューとゲームビューの右上隅にあります。カスタムギズモを追加するには、以下のコード例に示されているように、OnDrawGizmosコールバックを含むスクリプトを追加する必要があります。このスクリプトは、GameObjectの位置から3ワールドユニット前方に配置されたワイヤーフレームキューブを描画します。キューブのサイズは、クラスプロパティvsizeの型Vector3によって定義されます: public Vector3 vsize = new Vector3(1f, 1f, 1f);
void OnDrawGizmos()
{
// トランスフォームの位置に黄色のスフィアを描画する
Gizmos.color = Color.yellow;
Vector3 position = transform.position + transform.TransformDirection(Vector3.forward) * 3;
Gizmos.DrawWireCube(position, vsize);
}
ギズモのドロップダウンをクリックして可視性を制御します。OnDrawGizmosコールバックを持つスクリプトはすべてリストされます。
ドキュメントを確認して、Gizmoクラスの他の便利なメソッドについて学びます。
例外を投げることは、プログラムの実行中にエラーや例外的な状況が発生したことを示すためにプログラミングで使用される技術です。このメソッドを使用して、スレッドの実行を停止し、さらなる損害を防ぐことができます。
Unityでは、例外を投げることは他のプログラミング言語と同じように使用されます。
例外がスローされ、コード内でキャッチされずに処理されない場合、プログラムの実行は通常停止し、アプリから退出してオペレーティングシステムに戻されます。Unityでは、プログラムの実行が即座に停止し、ランタイム環境が例外を処理できる「キャッチ」ブロックを探します。キャッチブロックが見つからない場合、プログラムは終了し、例外はコンソールに記録されます。
例外をスローすることは役立ちます。これにより、エラーハンドリングロジックをプログラムの残りのロジックから分離でき、クリーンなコードを書くことに貢献します。例外をスローすることで、呼び出し元に何かが間違っていることを通知でき、戻り値やグローバルステートに依存してエラーを伝える必要がなくなります。
Unityで例外をスローするには、throwキーワードの後に例外オブジェクトを使用します。以下は例です:
if (target == null)
{
throw new System.NullReferenceException("target not set!");
}
エディターでコードを実行すると、スローされたエラーをキャッチし、Unityやアプリがクラッシュする代わりにDebug.LogError()を実行します。
Unityで例外を使用すると、早期にエラーをキャッチできます。エラーが発生した場所やその原因についての情報を提供することで、デバッグを容易にすることもできます。

これらの記事で、Unityプロジェクトのテスト、デバッグ、パフォーマンス向上についてさらに学びましょう:
これらの電子書籍でUnity開発者向けの高度なベストプラクティスと指示を深く掘り下げましょう:
Unityのベストプラクティスハブで、さらに多くの上級者向けリソースを見つけてください。