SteamVR Plugin 2.0のコントローラーの入力系の覚え書き

#はじめに
　初投稿なので文面が拙いですが、よろしくお願いいたします。

　SteamVR Pluginでコントローラーからの入力をしようとしたときに2.0では前バージョンの入力形式とは大幅に変わり、取得方法がよくわからないという人の為に記述しようと思います。

#実行環境
・Windows10
・Unity 2018.2.16f1
・SteamVR Plugin 2.0.1

・Oculus Rift + Touch
・Oculusソフトウェア、バージョン 1.32.0
・SteamVR バージョン 1539100633

#前バージョンとの違い
　前バージョンとの違いを簡単に表現すると、前バージョンでは始めから用意されていたボタンが、2.0では自分でボタンを用意しなければならなくなった感じです。

　全バージョンでは、ViveコントローラーやOculusのTouchコントローラーに対応させた特定の入力方法がありました。しかし、2.0からはその特定の入力方法がなくなり、自分で設定しなければならなくなりました。その要因の一つがKnucklesコントローラーで、5本指すべての入力が可能になったのでこれまで以上に入力方法が増えることになりました。そのことから、今後入力方法が多様化されると考えられたため、自分で必要なコントローラーの入力を設定する方式に変更されたそうです。理由が全然違うのであればすいません。(._.)

　自分で設定した項目はactions.jsonで保存されます。

　それでは、ここから入力方法の設定を行います。
　UnityのプロジェクトにSteamVR Plugin 2.0のアセットをインポートされている段階から始めます。
　なお、Oculus Riftの場合、PlayerSettingsでXRSettingsのOpenVRをOculusより上にしないとSteamVRが認識しないそうです。

#Actionの設定
1. 「Window」タブから「SteamVR Input」を選択します。
![スクリーンショット (927).png](https://qiita-image-store.s3.amazonaws.com/0/302367/38d8219c-ccf0-ce6b-0c30-28c37b75f008.png)

2. actions.jsonがないから作成するような表示が出るのでYesを選択します。
3. 以下のような設定画面が出るので、ここで設定します。
![スクリーンショット (928).png](https://qiita-image-store.s3.amazonaws.com/0/302367/cddedef3-bdbf-157e-cc73-4ab20081a0c2.png)
 Action Setsの欄で用途に応じた入力方法を分けることができます。
4. Action Setsの右端の"+"を選択し、名前を入力します。なお、大文字は後に正常に動かなくなるみたいなので小文字のみで入力します。
5. 下のActionsの欄に"+"を選択し、Actionを追加します。
6. Actionsの右側にAction Detailsという設定項目が出てくるので、Trigger等の名前や、そのActionで必要な情報タイプを設定します。
　情報タイプの一覧
　- boolean
　- vector1 (float)
　- vector2
　- vector3
　- pose
　- skeleton
　主にboolean,vector1,vector2あたりを頻繁に使用すると思います。
　設定すると、下のような感じになります。
![スクリーンショット (947).png](https://qiita-image-store.s3.amazonaws.com/0/302367/e8047a57-eeb0-5605-ebf7-c5bcb84245dd.png)
7. 設定が終わったら、Save and Generateでjsonファイルの保存と、入力情報取得時に必要になるファイルの作成が行われます。

#Bindingの設定
Actionの設定後、各Actionにコントローラーのボタンやトリガーを割り当てるためにBindingを行います。

1. 先程の設定していた画面の右下のOpen binding UIを選択します。ブラウザが開くので、そこで設定します。
2. ブラウザが開いたら、以下のような画面が出てき、Current BindingとあるところのEditを選択します。
![スクリーンショット (933).png](https://qiita-image-store.s3.amazonaws.com/0/302367/ebed9862-089a-5260-5985-f87656007a01.png)
3. 設定画面が出てくるので、作成したAction Setsのタブを開きます。
![スクリーンショット (938).png](https://qiita-image-store.s3.amazonaws.com/0/302367/0bec33cf-0420-c414-c352-b684f81bc184.png)
4. 各項目の"+"を選択し、必要な情報を入力します。（TRIGGERやBUTTON,JOYSTICK等が出てくるので選択した後、各々にあった項目を設定します）
![スクリーンショット (939).png](https://qiita-image-store.s3.amazonaws.com/0/302367/f7fb8823-3df2-cdc6-6d45-d024b0da4bb3.png)
![スクリーンショット (940).png](https://qiita-image-store.s3.amazonaws.com/0/302367/d084faf4-3836-3d25-75d3-ba6c1868b47e.png)
![スクリーンショット (941).png](https://qiita-image-store.s3.amazonaws.com/0/302367/99f3bed6-c1df-6476-e329-6449d0f93588.png)
※基本は必要ないと思いますが、真ん中にあるMirror Modeのチェックを外すと左右別で設定することもできます。

設定すると、以下のような画面になります
![スクリーンショット (943).png](https://qiita-image-store.s3.amazonaws.com/0/302367/2ff62800-26d2-7877-be96-516953744da8.png)
5. すべて設定した後、右下真ん中のReplace Default Bindingを選択し、Saveで設定を保存します。

これでBindingの設定は終わりです。

#入力値の取得方法
入力値を取得するには2つの方法があります。
　1. 変数定義で各Actionを保持させ取得する方法
　2. 各Actionを直接指定して取得する方法

また、どちらも共通している方式として
- ```using Valve.VR```を記述する
- GetState,GetAxisでbool値,float値などを取得
- 引数で右手,左手もしくは両手(どちらか)を選択
があります。

引数のほうは``` SteamVR_Input_Sources ```で指定します
- ```SteamVR_Input_Sources.LeftHand``` 左手
- ```SteamVR_Input_Sources.RightHand``` 右手
- ```SteamVR_Input_Sources.Any``` 両手(どちらか)

また、作成したAction Setsを選択しなければ入力されないので変数として作成します。

```public SteamVR_ActionSet myAction;```

そして、入力値を取得するタイミング(始めからの場合はStartやAwakeあたり)で取得できるように設定します。

``` myAction.ActivatePrimary(true); ```

1つ目の取得方法では変数定義を行う必要があるので定義します。

``` public SteamVR_Action_Single Trigger ``` float(vector1)
``` public SteamVR_Action_Boolean Button ``` boolean
``` public SteamVR_Action_Vector2 JoyStick ``` vector2
型名の最後に設定した型名（Boolean,Vector2等）がつくような形になっています。

そして、以下のようなかたちで値を取得します。
```float trigger = Trigger.GetAxis(handType); ```
```bool button = Button.GetState(handType); ```
```Vector2 joystick = JoyStick.GetAxis(handType); ```

2つ目の取得方法では、変数定義を行う必要がない分、一回の呼び出しの取得が長くなります。

型は以下のようになります。""で括ったところに各設定値を記述してください。
``` SteamVR_Input.__actions_"Action Setsの名前"_"Actionで追加した箇所(in,out)"_"actionの名前"."GetAxis,GetState(handtype)```

例
``` float trigger = SteamVR_Input.__actions_myinput_in_Trigger.GetAxis(handType); ```
``` bool button =  SteamVR_Input.__actions_myinput_in_Button.GetState(handtype); ```

のようになります。


上記で記述した取得方法で右手、左手の入力をTextで表示させるコードを以下に記述します。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
using UnityEngine.UI;

public class MyInput : MonoBehaviour {

    //取得する手（右手か左手か任意の手）
    public SteamVR_Input_Sources handType;

    //default以外のActionSetを取得する
    public SteamVR_ActionSet myAction;

    //入力取得方法１定義
    public SteamVR_Action_Single Trigger;

    public SteamVR_Action_Boolean Trigger_Touch;

    public SteamVR_Action_Single Grip;

    public SteamVR_Action_Vector2 JoyStick;

    public SteamVR_Action_Boolean JoyStick_Touch;

    public SteamVR_Action_Boolean JoyStick_Click;

    public SteamVR_Action_Boolean Button_X;

    public SteamVR_Action_Boolean Button_X_Touch;

    public SteamVR_Action_Boolean Button_Y;

    public SteamVR_Action_Boolean Button_Y_Touch;

    public SteamVR_Action_Boolean Button_A;

    public SteamVR_Action_Boolean Button_B;

    public Text text1;

    public Text text2;

	void Start () {
        //default以外のActionSetを取得できるように設定
        myAction.ActivatePrimary(true);
	}
	
	void Update () {
        string output = "";

        //左手の値を取得するように設定
        handType = SteamVR_Input_Sources.LeftHand;

        //クソザココード

        //入力取得方法１ 左手
        //Vector1,2,3は変数名.GetAxisで取得
        output += "Trigger = " + Trigger.GetAxis(handType) + "\n";

        //booleanは変数名.GetStateで取得
        output += "Trigger_Touch = " + Trigger_Touch.GetState(handType) + "\n";

        output += "Grip = " + Grip.GetAxis(handType) + "\n";
        output += "JoyStick = " + JoyStick.GetAxis(handType) + "\n";
        output += "JoyStick_Touch = " + JoyStick_Touch.GetState(handType) + "\n";
        output += "JoyStick_Click = " + JoyStick_Click.GetState(handType) + "\n";

        output += "Button_X = " + Button_X.GetState(handType) + "\n";
        output += "Button_X_Touch = " + Button_X_Touch.GetState(handType) + "\n";
        output += "Button_Y = " + Button_Y.GetState(handType) + "\n";
        output += "Button_Y_Touch = " + Button_Y_Touch.GetState(handType);

        text1.text = output;

        output = "";

        //右手の値を取得するように設定
        handType = SteamVR_Input_Sources.RightHand;

        //入力取得方法２ 右手
        #region Input_2
        output += "Trigger = " + SteamVR_Input.__actions_myinput_in_Trigger.GetAxis(handType) + "\n";
        output += "Trigger_Touch = " + SteamVR_Input.__actions_myinput_in_Trigger_Touch.GetState(handType) + "\n";
        output += "Grip = " + SteamVR_Input.__actions_myinput_in_Grip.GetAxis(handType) + "\n";
        output += "JoyStick = " + SteamVR_Input.__actions_myinput_in_JoyStick.GetAxis(handType) + "\n";
        output += "JoyStick_Touch = " + SteamVR_Input.__actions_myinput_in_JoyStick_Touch.GetState(handType) + "\n";
        output += "JoyStick_Click = " + SteamVR_Input.__actions_myinput_in_JoyStick_Click.GetState(handType) + "\n";

        output += "Button_A = " + SteamVR_Input.__actions_myinput_in_Button_A.GetState(handType) + "\n";
        output += "Button_B = " + SteamVR_Input.__actions_myinput_in_Button_B.GetState(handType);

        text2.text = output;
	}
}
```

また、変数を設定しなければならないので、GameObjectにアタッチした後に設定します。
![スクリーンショット (949).png](https://qiita-image-store.s3.amazonaws.com/0/302367/90c5cb35-febd-934f-a2e5-463475a99a41.png)

取得中の動画です。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">SteamVR Plugin 2.0でOculus Touchの入力を取得した動画 <a href="https://t.co/WtrImAblEs">pic.twitter.com/WtrImAblEs</a></p>&mdash; 天翔龍はたぽん＠μ&#39;sicForever (@TitaniaioEuropa) <a href="https://twitter.com/TitaniaioEuropa/status/1065402739100803072?ref_src=twsrc%5Etfw">2018年11月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

また、「window」タブから「SteamVR Input Live View」を開いても入力を取得しているかを確認することができます。
![スクリーンショット (948).png](https://qiita-image-store.s3.amazonaws.com/0/302367/5ead7103-9211-9a00-d988-9a19b201689f.png)

#おわりに
　長々と読んで頂きありがとうございました。
　まだ、自分もよくわからないところがあるのでこれで入力系をすべて理解できてはいないのですが、基本的な入力はできるようになると思います。
　これからも少しずつ記事を書いていければと思います。

#参考サイト
[SteamVR Plugin 2.0 セットアップ・サンプルシーンを動かすまでの備忘録](https://qiita.com/kyourikey/items/5967018e613b2fd49a1f)
[SteamVR Plugin 2.0 Input取得・入力関連スクリプト読み解き](https://qiita.com/kyourikey/items/232f7810769c7727c9bd)
[【Unity】SteamVR Plugin 2.0の入力方法を調べてみた](http://shop-0761.hatenablog.com/entry/2018/10/12/071507)
[The new SteamVR Input System and Unity](https://steamcommunity.com/sharedfiles/filedetails/?id=1416820276)
etc...