LoginSignup
1
3

More than 3 years have passed since last update.

アプリ内にサーバを立ててcurlでかんたんRPCするEasyHttpRpc

Posted at

GUIデバッグツールには限界がある

Unityに限らず、開発においてデバッグツールは必須です。
特にXR系の開発だと、実機で動かしながらあれこれパラメータを調整したい、このタイミングでこのイベント発火させたい、となることが多いと思います。
デバッグ用のUI作って、DebugManagerとか作って、設定ファイルパースして読み込んで、デバッグビルドのときだけ有効になるようにして……。
「そんなもん増えたり減ったりするのに毎回追従して作るのめんどくさくない……?」とわたしは常々思っていました。

  1. 機能の修正
  2. デバッグコードの修正
  3. デバッグUIの修正1

3段階も必要なのは正直言って苦痛です。「便利 > 手間」であるべきデバッグツールが、「手間 > 便利」になって、結果、デバッグツールを作った人くらいしかメンテをしなくなるか、誰も使わなくなるか、ということがよくあります。

EasyHttpRpc

というわけで、それを解決するためのデバッグツールを作りました。

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を開いて実行します。

    スクリーンショット 2021-03-18 3.49.45.png
    実行するとGameタブの左上とDebuggerにくっついているDebuggerPrimitiveSupplierにサーバのアドレスが表示されます。

  • http/rest.httpをVSCodeで開きます。

  • 画面に表示されたアドレスをrest.httpに入力します。

# enter your address
@baseurl = http://192.168.11.15:1234/

先程のスクリーンショットの環境をもとに入力するならこんな感じです。

  • APIを実行します。

execute-api.gif

まとめ

RPCって堂々と言うのは憚られるのでかんたんRPCって書きました。
任意のタイミングで実行できて返り値も出せるのでRPCっぽいなにかと名乗っても許してほしいところです。

基本的にGETを想定しています。引数に=?が含まれているとか改行コードがあるとかそういう面倒な問題に出くわしたときの回避策としてPOSTもいちおう入れてありますが、ほんとに入れただけです。
引数も返り値もstringで、使うところで使う人がパースする、と割り切りました。jsonはなにげに書くの面倒なのでGETのパラメータをそのままNameValueCollectionとして出しています。これくらいプリミティブにしておいたほうが変更に強いでしょう。

EasyHttpRpcはパラメータも込みでcurl叩ければなんでもいいので、htmlとかも返すようにしてやると、ブラウザから操作できるようになるので、非エンジニアの人でも操作できるようになっていいかもしれません。UIメンテナンス問題が復活しますが、UnityGUIいじるよりはhtmlを適当にぽちぽちするほうがまだましでしょう。

容赦なく非UIスレッドから実行されるので、そこだけは気をつけてください。
どうせ現代のアプリにおいて非同期処理は必須なので、とりあえずUniTask使ったらいいと思います。

ちくちく夜なべして作った甲斐あって、少なくとも自分が今使っている分にはいい感じです。
XRデバイスでの文字入力、つらい。

おしまい。

参考

スマホ実機でデバグ用のhttpサーバを動かしてみる
C# による簡易 HTTP サーバの実装
[VSCode] REST Client は変数を使うとAPIの環境やパラメータ変更が楽になる!
【Unity】カラーコードとColor型を変換する【C#】
GUIのフォントサイズ変更など


  1. 特にVRゴーグルやARグラスはデバッグに使える視野が限られている、いわば「画面が狭い」デバイスなのでデバッグメニュー作るのほんとつらい 

  2. 余談ですがこのツールThis is itって感じでめちゃくちゃ使いやすいです。IntelliJのやつとほぼ一緒なのがポイント。HoppscotchとかPostmanとかいろいろありますが、API叩きたいだけなのにアカウント要求やらなんやらされると、めんどくさくてイヤ。 

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3