GUIデバッグツールには限界がある
Unityに限らず、開発においてデバッグツールは必須です。
特にXR系の開発だと、実機で動かしながらあれこれパラメータを調整したい、このタイミングでこのイベント発火させたい、となることが多いと思います。
デバッグ用のUI作って、DebugManager
とか作って、設定ファイルパースして読み込んで、デバッグビルドのときだけ有効になるようにして……。
「そんなもん増えたり減ったりするのに毎回追従して作るのめんどくさくない……?」とわたしは常々思っていました。
- 機能の修正
- デバッグコードの修正
- デバッグUIの修正1
3段階も必要なのは正直言って苦痛です。**「便利 > 手間」であるべきデバッグツールが、「手間 > 便利」**になって、結果、デバッグツールを作った人くらいしかメンテをしなくなるか、誰も使わなくなるか、ということがよくあります。
EasyHttpRpc
というわけで、それを解決するためのデバッグツールを作りました。
アプリ内にサーバを立ててAPIを叩くことで、任意の引数を渡して任意のメソッドを実行し、ログを取得したりとかパラメータ変更したりとか、その他いろいろの操作ができるやつです。
要件
- 変更が簡易
テストを書き足すくらいの気軽さでデバッグツールも更新できる - 操作が簡単
説明がなくても見ればだいたいわかる - 標準機能のみ
特定のライブラリやAssetに依存しない - デバッグの環境の導入がかんたん
デバッグツールの実行に特殊なツールを要求しない
使い方
private EasyHttpRPC _easyHttpRPC;
private void Start()
{
// newするとサーバが起動する.CancellationTokenが必要.
// 任意でポート番号も指定できる.デフォルトは1234.
_easyHttpRPC = new EasyHttpRPC(this.GetCancellationTokenOnDestroy());
// 外から呼び出すメソッドを登録する.
_easyHttpRPC.RegisterRPC(nameof(Instantiate), Instantiate);
}
// 引数のNameValueCollectionにはGetのパラメータがそのまま入っている.
// Taskなので終了まで待ってからレスポンスを返せる.
private async Task<string> Instantiate(NameValueCollection arg)
{
await UniTask.SwitchToMainThread();
var argColor = arg["color"];
if (string.IsNullOrEmpty(argColor) || !ColorUtility.TryParseHtmlString(argColor, out var color))
{
color = Color.white;
}
var argCount = arg["count"];
if (!int.TryParse(argCount, out var count))
{
count = 0;
}
await _primitiveSupplier.Instantiate(color, count);
return "SUCCESS";
}
サンプルリポジトリ
EasyHttpRpcExample
サンプルのリポジトリです。
クラスも3つ、なにひとつ難しいことはしていないので、中身を見てもらえれば雰囲気はわかると思います。
-
VSCodeのプラグインREST Clientをインストールします。
REST Client
VSCodeのプラグインをインストールします。これ自体は名前の通りREST APIを実行するためのツールなので、curl
が実行できる環境があれば入れなくても大丈夫です。2 -
このリポジトリをクローンします。
-
Assets/Scenes/EasyHttpRPCExample.unityを開いて実行します。
実行するとGame
タブの左上とDebuggerにくっついているDebuggerPrimitiveSupplier
にサーバのアドレスが表示されます。 -
http/rest.httpをVSCodeで開きます。
-
画面に表示されたアドレスをrest.httpに入力します。
# enter your address
@baseurl = http://192.168.11.15:1234/
先程のスクリーンショットの環境をもとに入力するならこんな感じです。
- APIを実行します。
まとめ
RPC
って堂々と言うのは憚られるのでかんたんRPC
って書きました。
任意のタイミングで実行できて返り値も出せるのでRPC
っぽいなにかと名乗っても許してほしいところです。
基本的にGET
を想定しています。引数に=?が含まれているとか改行コードがあるとかそういう面倒な問題に出くわしたときの回避策としてPOST
もいちおう入れてありますが、ほんとに入れただけです。
引数も返り値もstring
で、使うところで使う人がパースする、と割り切りました。json
はなにげに書くの面倒なのでGET
のパラメータをそのままNameValueCollection
として出しています。これくらいプリミティブにしておいたほうが変更に強いでしょう。
EasyHttpRpcはパラメータも込みでcurl
叩ければなんでもいいので、html
とかも返すようにしてやると、ブラウザから操作できるようになるので、非エンジニアの人でも操作できるようになっていいかもしれません。UIメンテナンス問題が復活しますが、Unity
のGUI
いじるよりはhtml
を適当にぽちぽちするほうがまだましでしょう。
容赦なく非UIスレッドから実行されるので、そこだけは気をつけてください。
どうせ現代のアプリにおいて非同期処理は必須なので、とりあえずUniTask
使ったらいいと思います。
ちくちく夜なべして作った甲斐あって、少なくとも自分が今使っている分にはいい感じです。
XRデバイスでの文字入力、つらい。
おしまい。
参考
スマホ実機でデバグ用のhttpサーバを動かしてみる
C# による簡易 HTTP サーバの実装
[VSCode] REST Client は変数を使うとAPIの環境やパラメータ変更が楽になる!
【Unity】カラーコードとColor型を変換する【C#】
GUIのフォントサイズ変更など