変数の値を画面上にデバッグ表示できるUnity用OSS『Runtime Monitoring』について紹介します。
Unity 2021.3.0f1
Runtime Monitoring 2.1.4
はじめに
Runtime Monitoringを使うと、変数の値を画面上に簡単にデバッグ表示することができます。
変数にMonitorアトリビュートをつけるだけで画面上に変数の値をデバッグ表示してくれるUnity用OSS『Runtime Monitoring』
— Haruki Yano / Haruma-K (@harumak_11) 2022年8月29日
HPとかStateとか出したらデバッグが捗りそうです👏https://t.co/L6KMZ5aEHk pic.twitter.com/opYmUpUO4n
MIT ライセンスで公開されているOSSなので、ライセンスの範囲内で誰でも自由に使用することができます。
インストール方法は以下のリポジトリに書かれていますので、こちらを参照してください。
アセットストアからもインストールすることもできます。
本記事ではこのツールの使い方について簡単にまとめます。
基本的な使い方
MonoBehaviourの変数を監視する
MonoBehaviourの持つ変数をモニタリングするには、以下のように MonoBeahaviour.RegisterMonitor()
というメソッドを読んだ上で、モニタリングしたい変数に[Monitor]
アトリビュートをつけます。
using Baracuda.Monitoring; using UnityEngine; public sealed class Example : MonoBehaviour { // モニタリングしたい変数に [Monitor] 属性を付ける [Monitor] private int _test; private void Awake() { // このオブジェクトをモニタリング対象とする this.RegisterMonitor(); } private void Update() { _test++; } private void OnDestroy() { // このオブジェクトをモニタリング対象から外す this.UnregisterMonitor(); } }
これを適当なGameObjectにアタッチして再生すると左上に監視対象の値が表示されます。
いろんな登録方法
前節ではオブジェクトをモニタリング対象とするために MonoBehaviour.RegisterMonitor()
を呼びました。
これは以下のように書くこともできます。
//登録 MonitoringSystems.Resolve<IMonitoringManager>().RegisterTarget(this); //登録解除 MonitoringSystems.Resolve<IMonitoringManager>().UnregisterTarget(this);
MonoBehaviour の外側から登録を行いたい場合などにはこちらを使います。
また、MonitoredBehaviour
を継承したクラスを作成するとこれらの処理を基底クラスで行ってくれます。
using Baracuda.Monitoring; public sealed class Example : MonitoredBehaviour { // 省略 }
MonitoredBehaviour
の他、ScriptableObject 用の MonitoredScriptableObject
や C#の object 用の MonitoredObject
などが用意されています。
モニタリングできるもの
モニタリングできる対象は、フィールド、プロパティ、イベント、メソッドです。
using System; using Baracuda.Monitoring; public sealed class Example : MonitoredBehaviour { // フィールド [Monitor] private int _testField; // プロパティ [Monitor] private int TestProperty { get; } // イベント [Monitor] private event Action TestEvent; // メソッド [Monitor] private int TestMethod() { return 0; } }
イベントのモニタリング
前節の方法でイベントをモニタリングすると、下図のように登録されているリスナの情報一覧や、Invoke された数などが一覧表示されます。
ここまでの情報が不要である場合、以下のように Monitor
アトリビュートの代わりに MonitorEvent
アトリビュートを使い、引数を指定することで表示情報を制限できます。
// 発火した数とリスナの数だけを表示 [MonitorEvent(EventDisplay.InvokeCount | EventDisplay.SubCount)] public event Action TestEvent;
実行結果は以下のようになります。
メソッドのモニタリング
メソッドについては、 Monitor アトリビュートの代わりに MonitorMethod アトリビュートを使うことで引数を指定できます。
[MonitorMethod(123)] private int TestMethod(int input) { return input * 100; }
実行結果は以下の通りです。
挙動を変更するためのオプショナルなアトリビュート
出力する文字列をカスタムする MValueProcessor
以下のように MValueProcessor アトリビュートを使用するとモニタリング結果の文字列の出力を方法を変更することができます。
[Monitor] [MValueProcessor(nameof(Process))] private int _testInt; private string Process(int input) { return $"出力: {input}"; }
実行結果は以下の通りです。
表示する条件を設定する MShowIf
以下のように MShowIf アトリビュートを使用すると、モニタリング対象の値が条件を満たしていないときは表示を行わず、満たした時のみ表示できます。
//値が100以上の時のみモニタリング結果を表示 [Monitor] [MShowIf(Comparison.Greater, 100)] private int _testInt;
また、MShowIf の引数にメソッド名や変数の名前を与えると、それが true を返す時のみ表示を行うことができます。
[Monitor] [MShowIf(nameof(IsGreaterThan100))] private int _testInt; private bool IsGreaterThan100() { return _testInt > 100; }
更新タイミングを指定する MUpdateEvent
モニタリング対象の値は、モニタリングを行うために毎フレーム取得されます。
そのため、例えば以下のように transform.position をモニタリングすると、毎フレーム transform へのアクセスが行われることで無駄な処理負荷がかかってしまう可能性があります。
[Monitor] private Vector3 Position => transform.position;
MUpdateEvent アトリビュートを使うと、引数として指定したイベントが発火した時だけ、モニタリング対象の値を取得して表示を更新します。
つまり以下のように必要な時だけプロパティにアクセスしてモニタリングすることが可能になります。
using System; using Baracuda.Monitoring; using UnityEngine; public sealed class Example : MonitoredBehaviour { [Monitor] [MUpdateEvent(nameof(Moved))] // Movedが呼ばれた時のみモニタリングするためにプロパティから値を取得 private Vector3 Position => transform.position; public void Update() { if (Input.GetKey(KeyCode.Space)) { transform.position += Vector3.forward; Moved?.Invoke(); } } private event Action Moved; }
モバイルサポートしてるか?
本ライブラリはREADMEを見る限り、モバイルデバイスでの動作は未検証と書かれています。
そこで検証用のプロジェクトを作成し手元の iOS/Android で動かしてみましたが、問題なく動いていることを確認できました。
プロジェクトの詳細などはツイートからのリンクを参照してください。
Runtime Monitoring、モバイルプラットフォームでの動作は未検証とあったので動かしてみましたが iOS/Android 普通に動きました。
— Haruki Yano / Haruma-K (@harumak_11) 2022年9月6日
検証リポジトリ: https://t.co/uf9WAvGXJS https://t.co/DNvuj1fiPc pic.twitter.com/CRjzUIw3b2
その他の機能
本記事では Runtime Monitoring の基本的な使い方だけを紹介しました。
この他にも、モニタリング対象にタグをつけて表示するものをフィルタリングしたり、背景色や文字色・レイアウトなどの装飾を変えるアトリビュートがあったりします。
この辺りは、基本的な使い方に慣れてきたタイミングで README を一読することをお勧めします。