[Oculus+Unity]VR空間内にデバッグログを表示するディスプレイを作る - CanvasWithDebugの利用

2020年10月25日

UnityとOculusQuest2を使用してアプリのテストを行っていると、デバッグ情報の確認が一苦労であることに気付きます。

動作確認を行うには、通常、VRゴーグルを覗く必要があります。ゴーグルを装着した状態では、PC画面は見られません。その上、初期設定ではデバッグ情報表示に使用する Debug.Log が動作しないようです。

今回は"Oculus Integration"に含まれるサンプル「DebugUI」のプレハブとスクリプトを利用・改造し、VR空間内にデバッグ情報を表示するディスプレイを表示する例を紹介します。

CanvasWithDebug.prefabをシーンに追加

CanvasWithDebug.prefab は以下のパスに存在します。

Assets/Oculus/SampleFramework/Core/DebugUI/Prefabs/CanvasWithDebug.prefab

CanvasWithDebug.prefabのパス

これをシーンのヒエラルキーに追加してください。インスペクターに以下の警告が出る場合がありますが、無視して構いません。

CanvasWithDebug.prefabをシーンに追加した際に出る警告

DebugUISample.csを改造

サンプルに含まれるスクリプト DebugUISample.cs のソースをコピーし、新しいスクリプト(ここでは MyDebugUI.cs とします)を作成し、以下のように編集します。

using UnityEngine;
using UnityEngine.UI;

public class MyDebugUI : MonoBehaviour
{
    bool inMenu;

    void Start ()
    {
        DebugUIBuilder.instance.AddLabel("Debug Start", DebugUIBuilder.DEBUG_PANE_CENTER);
        DebugUIBuilder.instance.AddLabel("Debug Log", DebugUIBuilder.DEBUG_PANE_LEFT);
        DebugUIBuilder.instance.Show();
        inMenu = true;
    }

    void Update()
    {
        // Bボタンでデバッグディスプレイの表示・非表示
        if (OVRInput.GetDown(OVRInput.Button.Two))
        {
            if (inMenu) DebugUIBuilder.instance.Hide();
            else DebugUIBuilder.instance.Show();
            inMenu = !inMenu;
        }

        // Aボタンでデバッグログをクリア
        if (OVRInput.GetDown(OVRInput.Button.One)) {
            DebugUIBuilder.instance.Clear();
            DebugUIBuilder.instance.AddLabel("Clear");
            DebugUIBuilder.instance.AddDivider();
        }
    }
}

この MyDebugUI.cs を、シーン内の適当なゲームオブジェクト(空のオブジェクトでも構いません)に追加してください。

DebugUIBuilder.csにログクリアの機能を追加

そのままではログ情報が消えずログウィンドウが縦に長くなってしまうので、ボタンでログを消去できるようにします。

CanvasWithDebug.prefab に含まれるスクリプト DebugUIBuilder.cs に以下のメソッドを追記してください。

……

public void Clear() {

    // 追加されるUI要素を初期化
    insertedElements[DEBUG_PANE_CENTER].Clear();
    
    // すでに追加されているUI要素を削除
    foreach (Transform child in targetContentPanels[DEBUG_PANE_CENTER].gameObject.transform)
    {
        Destroy(child.gameObject);
    }

    // 表示の更新
    if (gameObject.activeInHierarchy)
    {
        Relayout();
    }
}

……

定数 DEBUG_PANE_CENTER は、ディスプレイの中心の列を意味します。左右の列の情報も消したい場合は for でループ処理させてください。

デバッグ情報の書き込み

スクリプトの任意の位置に AddLabel でテキストを書き込めます。

DebugUIBuilder.instance.AddLabel("書き込まれるテキスト");

例えば、あるプレハブを作成する Update の中でデバッグ情報を書き込むには以下のように記述します。

void Update()
{
	// waitTime が経過する毎にプレハブを作成
    timer += Time.deltaTime;
    if (timer > waitTime)
    {
        timer = timer - waitTime;
        Instantiate(
			cubePrefab, 
			new Vector3(transform.position.x - 0.5f, 0, transform.position.z), 
			Quaternion.identity);

        // デバッグログに書き込む
        DebugUIBuilder.instance.AddLabel("Spawn!");
    }
}

実行結果

ログを表示したディスプレイが表示されます。ボタンで表示・非表示を切り替えられます。

デバッグログを表示するサンプル1

クリアを行えば、今まで書かれたログを全て消すことができます。

ログをクリア後のデバッグディスプレイ

以上によってVR空間内にデバッグログが表示できるため、ゴーグルを装着したまま情報を確認することが可能です。

ログを表示することだけを目的とした場合、不要な機能が多く残っていますので適宜編集してください。

おまけ:UIボタンでログを消去する

コントローラのボタンではなくゲーム内UIのボタンを追加し、それによってログの消去を行うには MyDebugUI.cs を以下のように書き換えてください。

using UnityEngine;
using UnityEngine.UI;

public class MyDebugUI : MonoBehaviour
{
    bool inMenu;
    private string buttonText = "Clear Log";

    void Start ()
    {
        DebugUIBuilder.instance.AddButton(buttonText, ClearButtonPressed);
        DebugUIBuilder.instance.AddDivider();
        DebugUIBuilder.instance.Show();
        inMenu = true;
    }

    void Update()
    {
        if (OVRInput.GetDown(OVRInput.Button.Two))
        {
            if (inMenu) DebugUIBuilder.instance.Hide();
            else DebugUIBuilder.instance.Show();
            inMenu = !inMenu;
        }
    }

    void ClearButtonPressed()
    {
        DebugUIBuilder.instance.Clear();
        DebugUIBuilder.instance.AddButton(buttonText, ClearButtonPressed);
        DebugUIBuilder.instance.AddDivider();
    }
}

VR空間内のUIボタンでログを消去

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です