dwgx@blog:~$dwgx
> cd ../posts

VRChat のワールド内で本物のブラウザを操作する(VRCBrowserBridgeWorld)

// created

VRCBrowserBridgeWorld は VRChat のワールド内で本物のブラウザを操作する実験だ。人はワールドに立ってスクリーンに向かってクリックやドラッグをし、キーを叩く。もう一方では本物のブラウザがそれに追従して動き、その映像がワールドへ押し戻される。要は VRChat をリモートデスクトップの入力側として使っているわけだ。

このリポジトリはワールド側、つまり UdonSharp の半分だけだ。実際にブラウザを駆動して RTSP ストリームを押し戻す外部ゲートウェイはここにはなく、別途動かす必要がある。境界は最初からはっきり引いてある。ワールドはプレイヤーの操作をイベントに変えて送り出すだけで、汚れ仕事はすべて外に投げる。

中核はカスタムプロトコルだ。インタラクションごとに 1 行の JSON にシリアライズし、VRCBRIDGE プレフィックスを付けてログに書き込む。外部ゲートウェイがログを tail しつつ Udon の同期変数を拾うことで、イベントを取り出せる。イベントはこんな形だ:

{"v":1,"sessionId":"demo","seq":1,"playerId":"1","playerName":"ExampleUser","source":"gateway","type":"pointer_down","x":0.5,"y":0.5,"button":"left"}

座標 x/y は正規化した UV で 0 から 1。外側はスクリーンがワールド内でどれだけ大きいか、どちらを向いているかを気にする必要がなく、比率に沿って本物のウィンドウにマッピングすればいい。イベントタイプはほぼ全部をカバーしている。ポインタ移動/押下/離す、スクロールホイール、テキスト、URL、キー入力、ビューポート、ストリーム設定、それに戻る/進む/リロード。イベント送信はすべて BridgeRouter を経由し、JSON を組み立て、Udon の手動同期変数で送り、ついでにログを書く。

VRChat にマウスはないので、スクリーンをクリックするのはレイキャストで行う。BridgeInputSurface はプレイヤーの頭からそのクアッドへレイを一本飛ばし、命中点を UV に変換し、座標に沿ってポインタやスクロールを送る——頭を向けた先がカーソルになる。ポインタ移動にはスロットリングを入れてある。そうしないと頭を一回回しただけで move イベントの連打がログを溢れさせる。その上に BridgeCommandButton がそれぞれ 1 つのアクションにマッピングされ、BridgeControlPanel がもう一層ラップしてワンクリックにまとめる。映像の戻りは AVPro RTSP を通り、デフォルトは rtsp://127.0.0.1:8554/browser を指す。

Udon のシーンを手作業で組むのはあまりに苦痛なので、メニュー VRC Browser Bridge/ の下に一式のエディタツールを用意した。Build Bridge Console をワンクリックすれば、マテリアル、コンソールスクリーン、コマンドパネルをすべて生成してくれる。UdonSharp の program asset はしょっちゅう壊れるので、Repair のワンクリック修復を追加した。さらにワールドに入らなくてもプロトコルが正しいか検証できるテスト項目が 2 つある。プロジェクトはまだかなり WIP で、Unity 2022.3.22f1 と UdonSharp をベースにしており、リポジトリに license は置いていない。