LoginSignup
33
24

More than 3 years have passed since last update.

Oculus Questコントローラーが持つ複数のキーマッピングについて

Last updated at Posted at 2019-06-17

はじめに

Oculus Questの入力周りのドキュメントを読んで、ざっと概要をまとめてみました。
その中で少し特殊なキーマッピングついての部分についての説明をします。

OVRInput
https://developer.oculus.com/documentation/unity/latest/concepts/unity-ovrinput/

この話はOculus Questに限らないOculus関連デバイス共通の話ですが、他の環境での動作は未確認です。

環境

  • Unity 2018.3.14f1
  • Oculus Integration for Unity - 1.37
    • Oculus Utilities Plugin 1.32.0
  • Mac OSX 10.14.4(18E226)

Oculusコントローラーのざっくりした基本

Oculus Quest / Rift Sのコントローラーは共通なのですが、どちらも"Oculus Touch"と呼ぶそうです。旧Riftコントローラーと入力自体は同じですが、少なくともドキュメント上では区別されていないようです。

入力はこんな感じで拾います。staticメソッドでアクセス出来るので、ほぼほぼUnity標準のInputクラスと同様に扱えます。

void Update()
{
    // Aボタン押しっぱなしの時
    bool IsButtonAPressing = OVRInput.Get(OVRInput.Button.One);
    // Xボタンを押した瞬間
    bool IsButtonXPressed = OVRInput.GetDown(OVRInput.Button.Three);
    // 左手ジョイスティックに触れている時
    bool IsLStickTouching = OVRInput.Get(OVRInput.Touch.PrimaryIndexTrigger);
    // 左手ジョイスティックの傾けた値
    Vector2 RStickVec = OVRInput.Get(OVRInput.Axis2D.SecondaryIndexTrigger);
}

OVRInput.Get()の第一引数は複数の型でオーバーロードされており、OVRInput.Buttonの他に接触状態を取得するOVRInput.Touchや連続値として取得するOVRInput.Axis1D,OVRInput.Axis2Dなどがあります。返ってくる値もboolだけでない点に注意です。

コントローラーのキーマッピング

上記では説明を省略しましたが、OVRInput.Get()は第二引数にOVRInput.Controllerが指定できるようになっています。

OVRInputの定義.cs
public static bool Get(Button virtualMask, Controller controllerMask = Controller.Active);

これは対象となるコントローラーを指定するもので、省略した場合は有効なものが自動的に設定されています。Oculus Questの場合、ここに指定出来る値が二種類あり、どちらを指定するかによってキーマッピングが変化します(重要)。

複合コントローラーをとして扱う場合

両手2つのコントローラーを、一つの複合的(Combined)なものとして使った場合のキーマッピングです。

第二引数でOVRInput.Controller.Touchを指定した場合が該当します。Touchコントローラーが両手分繋がっている場合はこれがデフォルトです(細かく条件変えて確認したりはしてないです)。先程のサンプルコードもこちらのキーマッピングで書いてあります。

64515613_622041711631269_1500694343822868480_n.png

左手と右手はPrimary,Secoundaryというprefixで区別されています。A,B,X,Yボタンは、OVRInput.Button.One, OVRInput.Button.Twoと続きます。

個々のコントローラーをとして扱う場合

両手2つのコントローラーを、それぞれ独立した(Individual)コントローラーとして扱い場合のキーマッピングです。

第二引数でOVRInput.Controller.LTouchもしくはOVRInput.Controller.RTouchを指定した場合が該当します。Touchコントローラーが片手分繋がっている場合は、どちらかがデフォルトになる気がします(未確認)

64700495_622041714964602_2286289187051143168_n.png

複合的に扱う場合と異なるのは、左右の区別がない点です。左手のXキーと右手のAキーに同様の振る舞いを与えることが出来ます。

追記

キーマッピングの使い分け

多くの場合は前者の複合的な扱いをすることが多いと思いますが、特定の状況で左右を区別しない入力が活躍すると思います。

「トリガーを引いて銃を撃つ」機能を例に考えます。銃はどちらの手で持つこともできますが、普通持っている側のコントローラーでトリガーを引いた場合のみ発射ができると思います。

複合的な扱いをしている場合、銃を持っていることを管理するクラスでは「右手で持っている場合はOVRInput.Button.SecondaryIndexTriggerを、左手ではOVRInput.Button.PrimaryIndexTrigger」というような分岐を書く必要があります。

ここで左右を区別しない指定が出来ると、銃を持っている手の指定(OVRInput.Controller.LTouch,OVRInput.Controller.RTouch)のみ外部から指定出来るようにしておき、第一引数に渡す値はOVRInput.Button.PrimaryIndexTriggerと共通化しておけます。「持っている手に関わらずトリガーを引いたら銃がでる」という実装をする場合、こちらの方が直感的で分かりやすいコードになります。また、例えば「グリップを引いて弾をリロードする」という実装をする際にも対応が簡単だと思います。

最後に

キーマッピングが2つあることを見て一瞬混乱したんですけど、普通に便利そうな機能でした。特に個々に扱うモードでは機能ごとに入力を管理するような上手い実装ができると気持ちよさそうだと感じました。

もし間違っていることとかあれば教えてください〜

関連

33
24
1

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
33
24