以前、WebXRのimmersiveモードとBabylon.jsについて紹介したことがありました。
このときは、VRモード切り替え、テレポート、コントローラを別の3DCGモデルに変更する方法などを紹介しましたが、コントローラの個別のボタン入力の方法が未記載でした。
かなり時間が経ってしまったのですが、コントローラのボタン入力方法を確認できたので、サンプルコード付きでまとめました。
なお、動作確認はOculus Quest2で行っています。
2021/5/9追記
Babylon.js Documentationに個別のボタン入力方法についての説明とサンプルコード (PlayGround) をpull requestし、マージされました
- 1. WebXR準拠のコントローラ入力について
- 2. Babylon.jsによるWebXRのVRコントローラー入力方針
- 3. Babylon.jsによるWebXRのVRコントローラ入力の書き方
- 4. おわりに
1. WebXR準拠のコントローラ入力について
WebXR Device APIとして、このサイトの中でコントローラ入力について説明があります。
説明後半の「the WebXR Input Profiles Registry」のリンクからGitHubに飛んで、profilesというフォルダを選択すると、WebXRに準拠したデバイスの製造元のフォルダを確認できます。
必要なデバイスを選択するとボタン入力に関するjsonファイルがあります。たとえばoculus-touch-v3.json (おそらくOculus Quest2のコントローラ) をみると、このような記載があります。
ここに書かれたcomponentsの中の要素が、コントローラに割り当てられたボタンです。
もう少し直感的に理解するには、コントローラの割り当て確認サイトを使うのが良いです。このリポジトリのソースコードで動いています。
このように、どのボタンがどのIDなのかがわかります。コントローラを右手に変更することもできます。
2. Babylon.jsによるWebXRのVRコントローラー入力方針
公式ドキュメントはこちらです。
しかし、なぜかPlayGroundによるサンプルコードが入っておらず、断片的なコードしかありませんでした。そのため、まだWebXRでのやり方をきちんと理解できていない私だとよくわかりませんでした。
大まかに言うと、motionControllerとしてのコンポーネントを複数の手段のどれかを使って取得し、コンポーネントに対して処理を書いていく流れです。
取得手段1:WebXR Device APIで規定された名称を直接取得する
例
const triggerComponent = motionController.getComponent("xr-standard-trigger");
取得手段1':WebXR Device APIで規定されたidを直接取得する
例
const xr_ids = motionController.getComponentIds();
xr_idsにはコントローラの入力がマッピングされたjsonファイルのcomponentsの名称が入ります。これを配列として、xr_ids[0], xr_ids[1], ..として使います。
取得手段2:WebXR Device APIで規定されたtypeを直接取得する
例
const squeezeComponent = motionController.getComponentOfType("squeeze");
ただ、これだと先ほどのWebXR Device APIでは、Oculus Quest2のA, B, X, Yボタンは全てtype:buttonだったので区別がつかないかもしれません。
いくつか調べていたところ、取得手段1'の方法でcomponentを作り、コントローラの入力を設定する方法を書かれているサイトを見つけました。
そこで、この内容を参考にしつつ、直感的にわかるようにキー入力で変化が起きるようにしました。また、簡単に試せるようにPlaygroundで動くようにしました。
3. Babylon.jsによるWebXRのVRコントローラ入力の書き方
まず、Oculus Quest2では、WebXR Device APIでのキー割り当てはこのようになっています。
Babylon.jsの中でサポートしているIDを調べたところこうなっていました。
調べた方法
console.logの出力結果を整理したものです。
[left controller]
xr-standard-trigger
xr-standard-squeeze
xr-standard-thumbstick
x-button
y-button
thumbrest
[right controller]
xr-standard-trigger
xr-standard-squeeze
xr-standard-thumbstick
a-button
b-button
thumbrest
今回はこの中でthumbrest以外のボタンが押されると、sphereまたはcubeが拡大、縮小、移動 (thumbstick割り当てのみ) という単純なサンプルを書きました。
sphereとcubeの割り当てです。
ボタン入力についてはこのように書きました。他のボタンも同様です。
thumb stickについてはこうです。
ただ、Babylon.jsのWebXRでVRモードにすると、左右のthumbstickのX変位がカメラ向き移動に使われます。そのため、今回の書き方だとthumb stickのY方向は問題ないですが、X方向の入力を入れると合わせてカメラも移動してしまいます。解決方法がわかったら追記します。
全てを書いたものは以下のPlayGroundにあります。
WebXR_motion controller input sample on PlayGround
Ocuus Quest2のブラウザでこのURLにアクセスすると確認できます。このようになります。
ちなみに、thumbrestについては動きが取れませんでした。thumbrest自体よくわかっていないのですが、Oculus公式のサイトをみるとおそらくthumb stickに触れているかどうかなのだと思われます。
わかったら追記します。
Oculus Touch (L) Thumbstick CapTouch - 左コントローラーのサムスティックの静電容量式タッチイベント。[Axis Value (軸値)]は、ユーザーがサムスティックに触れている場合は1を返し、触れていない場合は0を返します。
引用元:Oculus Controller Input Mapping | Oculus Developers
なお、今後使うことはないと思われますが、WebVRモードでのキー割り当てについては以前書いたとおりです。
4. おわりに
シンプルな例ですが、WebXRでのコントローラ入力が整理できたので、Babylon.js Editorで動くようにサンプルコードを準備したいと思います。