SteamVR のコントローラー入力は汚くなりがち

こんにちは。VR開発やってますか?
ゲームなどの描画処理を行うフレームワークにおける入力の特徴として、入力をイベントとして扱うのではなくフレームごとにif文を用いて状態をチェックすることで入力を受け取るというものがあります。
しかし、受け取りたい入力の種類が増えればどんどんif文は長くなっていきますし、可読性も失われていきます。
そして入力を受け取るためのメソッドが太りすぎて非常に汚くなり、メンテナンスがしにくくなるということがありがちです。

SteamVRを用いたコントローラーからの入力処理も同様なうえ、入力される場所(ボタン)が数値のID方式で与えられるため、別で定義されたマスクを通してボタンの名前と数値IDを一致させなければいけません。

少しだけならまだ良いかもしれませんが、色んな場所で入力に応じた操作を行うようになってくるとかなりストレスフルです。

入力ってイベントだよね

C#などを用いてアプリを書く高レイヤーの人間にとって入力はイベントです。実際、逐次処理で条件を書き連ねていって状態をチェックするよりも、イベントが発行されたら何かをするという流れの方がより人の自然な考え方に近いですし、なによりコードがキレイです。

そういうわけで、UniRxを使って入力を監視可能な状態変数のストリームにするというラッパーを書きました。
要するに入力がSubject(監視対象)のObserverパターンでいろいろできて嬉しいというやつです。
簡単な入力の受信くらいであれば、LINQがわかれば簡単に使えます。

SteamVRInputRx

このラッパーではSteamVRControllerStateという列挙体でコントローラー入力の状態を表します。
基本的に「押した」「押している」「離した」の三種類の状態があり、この順番で流れてきます。

使い方

準備

まずはSteamVRInputRx.csとSteamVRControllerState.csをダウンロードしてプロジェクトに追加してください。
あとはSteamVRInputRxをコントローラーのオブジェクトにアタッチ(AddComponent/コンポーネントとして追加)するだけです。
Viveのように複数コントローラーがある場合はそれぞれにアタッチして別々に受け取れます。

入力受け取り

アタッチされたスクリプトをGetComponentなどで取得して、SteamVRControllerStateの変更を監視することで入力を受け取れます。
例えば以下のような使い方ができます。

このコードをMonoBeheviourを継承したクラスのStart内に書き、そのスクリプトをコントローラーにアタッチすれば実行できます。

まとめ

よく使いそうな項目だけ網羅的に実装しました。つまり若干雑です。コントローラーによっては抜けや使われない項目もあるかと思います。
好きなように改造して使ってください。

まとめとしてはRxはいいぞということで。

スポンサーリンク