【Unity】オブジェクトの情報をシーンビューにデバッグ表示する

こじゃらこじゃら

キャラクターの情報をシーン上に表示する手軽な方法はないの?

このはこのは

Handlesクラスの機能を使えば実現できるわ。

スクリプトで保持する変数などの情報をシーンビューにデバッグ表示する方法の紹介です。

本記事の手順を実践すると、次のようにオブジェクトの位置に任意のデバッグ文字列を表示できるようになります。

このようなテキスト表示は、次のようなコードで手軽に表示できます。

// 表示させたい変数
float value;

・・・(中略)・・・

// シーンビューに変数の値を表示
Handles.Label(transform.position, $"変数の値 : {value}");

本記事では、このようなシーンビューにデバッグ情報を表示する方法を解説していきます。

なお、ラベル表示はUnityエディタ上でのみ動作し、実行時には動作しません(ビルドから除外する必要がある)ので予めご了承ください。

動作環境
  • Unity 2022.1.9f1

スポンサーリンク

前提条件

次のようにシーン上にデバッグしたい対象のオブジェクトが配置されているものとします。

本記事では、上記のキューブの位置にデバッグ用のテキストを表示していくことを例として解説を進めていきます。

ラベル表示の実装

テキスト表示には、UnityEditor.Handles.Labelメソッドを使います。

次のように複数のオーバーロードされたメソッドが提供されています。

public static void Label(Vector3 position, string text);
public static void Label(Vector3 position, string text, GUIStyle style);

割愛したものがありますが、ラベル表示のためのメソッドは上記2つとなります。

第1引数positionには、ラベルを表示したいワールド位置を指定します。

第2引数textには、ラベル表示したい文字列を指定します。

第3引数styleには、テキストのスタイルを定義する情報GUIStyle型のインスタンスとして指定します。

注意

UnityEditor.Handles.LabelメソッドはUnityエディタ専用のメソッドのため、表示用のコードはビルドには含まれないようにご注意ください。含まれるとコンパイルエラーとなります。

サンプルスクリプト

以下、オブジェクトの名前と位置をシーンビュー上にラベル表示するサンプルスクリプトです。

SceneViewDebugExample.cs
using UnityEngine;

// Unityエディタ時のみusingする必要がある
#if UNITY_EDITOR
using UnityEditor;
#endif

public class SceneViewDebugExample : MonoBehaviour
{
    // Unityエディタ時のみGizmo表示を行う
    #if UNITY_EDITOR
    private void OnDrawGizmos()
    {
        // 自身のオブジェクト名
        var objectName = name;

        // 自身のオブジェクトのワールド位置
        var worldPos = transform.position;
    
        // オブジェクトの位置に「オブジェクト名 : 位置」という形式でラベル表示
        Handles.Label(worldPos, $"{objectName} : {worldPos}");
    }
    #endif
}

上記スクリプトをSceneViewDebugExample.csという名前で保存し、ラベル表示を適用したいゲームオブジェクトにアタッチすると機能するようになります。

実行結果

オブジェクト名と位置がシーンビュー上にリアルタイムに表示されるようになりました。

スクリプトの説明

Handlesクラスを使えるようにするため、先頭でUnityEditor名前空間をusingしています。

// Unityエディタ時のみusingする必要がある
#if UNITY_EDITOR
using UnityEditor;
#endif

Unityエディタ時しか使えないため、#if~#endifのプリプロセッサディレクティブで囲んでいます。

シーンビュー上にラベルを表示する処理は以下部分です。

// Unityエディタ時のみGizmo表示を行う
#if UNITY_EDITOR
private void OnDrawGizmos()
{
    // 自身のオブジェクト名
    var objectName = name;

    // 自身のオブジェクトのワールド位置
    var worldPos = transform.position;

    // オブジェクトの位置に「オブジェクト名 : 位置」という形式でラベル表示
    Handles.Label(worldPos, $"{objectName} : {worldPos}");
}
#endif

例では、シーンビューに常にテキスト表示させるため、OnDrawGizmosイベント内部でラベル表示を行うようにしています。

Handles.Labelメソッドの引数に自身のオブジェクト位置と表示文字列を渡しています。

オブジェクトを選択した時のみラベル表示させる

OnDrawGizmosイベント内で表示させていたものをOnDrawGizmosSelectedイベント内に変更すれば良いです。

サンプルスクリプト

SceneViewDebugSelectedExample.cs
using UnityEngine;

// Unityエディタ時のみusingする必要がある
#if UNITY_EDITOR
using UnityEditor;
#endif

public class SceneViewDebugSelectedExample : MonoBehaviour
{
    // Unityエディタ時のみGizmo表示を行う
#if UNITY_EDITOR
    // 選択中のみラベル表示
    private void OnDrawGizmosSelected()
    {
        // 自身のオブジェクト名
        var objectName = name;

        // 自身のオブジェクトのワールド位置
        var worldPos = transform.position;
    
        // オブジェクトの位置に「オブジェクト名 : 位置」という形式でラベル表示
        Handles.Label(worldPos, $"{objectName} : {worldPos}");
    }
#endif
}

上記スクリプトをSceneViewDebugSelectedExample.csという名前で保存し、対象のゲームオブジェクトにアタッチします。

実行結果

選択されたオブジェクトに対してのみラベル表示されるようになりました。

スクリプトの説明

以下部分がOnDrawGizmosからOnDrawGizmosSelectedに変わっています。

// 選択中のみラベル表示
private void OnDrawGizmosSelected()

これ以外は1つ目の例と一緒です。

さいごに

シーンビュー上にデバッグ情報をラベル表示させるようにすることで、デバッグログが見づらくなる問題を解決できる場合があります。

エディタ専用の機能ではありますが、大量のオブジェクトに対してラベル表示させると処理負荷が増大してUnityディタの操作が重くなることがある点にはご注意ください。

UnityEditor.Handlesクラスには、テキスト表示以外にも線や円などを表示したりといったメソッドが用意されているため、興味がある方は以下公式リファレンスをご覧ください。

参考サイト

スポンサーリンク