magicleap入門-タッチパッド入力を受け取りたい

# はじめに
C#初心者かつunity初心者magicleapのチュートリアルを追っていき，その際に調べたことをメモしていきます．そのため基本的な文法の内容とスクリプトの構造自体についての内容が混在していますのでご注意ください．

# これは何をやりたいのか
magicleapのコントローラにはタッチパッドがついていてその入力を受け取ることができます．この入力を受け取ってみましょう．

# unityエディタでの準備
unityエディタでの準備は[2.3 タッチパッドジェスチャーUnity](https://developer.magicleap.com/ja-jp/learn/guides/touchpad-gestures-tutorial-unity)の通りやっていくと問題なくできましした．
# C#スクリプトを書く
参考にしたのは[2.4 Touchpad Gestures - Unity](https://developer.magicleap.com/en-us/learn/guides/touchpad-gestures-tutorial-unity)です．この内容を読み解いていきます．

```C#:TouchpadGestures.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.MagicLeap;

public class TouchpadGestures : MonoBehaviour {

    #region Public Variables
    public Text typeText, stateText, directionText;
    public Camera Camera;
    #endregion

    #region Private Variables
    private MLInput.Controller _controller;
    #endregion

    #region Unity Methods
    void Start() {
        MLInput.Start();
        _controller = MLInput.GetController(MLInput.Hand.Left);
    }

    void OnDestroy() {
        MLInput.Stop();
    }            

    void Update() {
        updateTransform();
        updateGestureText();
    }
    #endregion

    #region Private Methods
    void updateGestureText() {
        string gestureType = _controller.CurrentTouchpadGesture.Type.ToString();
        string gestureState = _controller.TouchpadGestureState.ToString();
        string gestureDirection = _controller.CurrentTouchpadGesture.Direction.ToString();

        typeText.text = "Type: " + gestureType;
        stateText.text = "State: " + gestureState;
        directionText.text = "Direction: " + gestureDirection;
    }
    
    void updateTransform() {
        float speed = Time.deltaTime * 5.0f;

        Vector3 pos = Camera.transform.position + Camera.transform.forward;
        gameObject.transform.position = Vector3.SlerpUnclamped(gameObject.transform.position, pos, speed);

        Quaternion rot = Quaternion.LookRotation(gameObject.transform.position - Camera.transform.position);
        gameObject.transform.rotation = Quaternion.Slerp(gameObject.transform.rotation, rot, speed);
    }
    #endregion
}
```

できるだけ初歩的なものからメモしていきたいと思います．

### `using ○○`
これはCでいうライブラリヘッダと同じようなものだと考えます．特定のものを宣言することによってそのこに所属するクラスを宣言することができるようになります．

### `#region Public Variables~#endregion`
これは表記の可読性を上げるためのコードです．これで囲んだ範囲をIDE上で折りたたむことができます．

### `public Text typeText, stateText, directionText;`
publicによりスクリプトの外側からつける形で宣言された，タッチパッドに入力された状態を表示させるための文字列を格納するクラスです．`using UnityEngine.UI`を宣言することで使えるようになります．これによりtextゲームオブジェクトを登録することができます．

### `public Camera Camera;`
カメラに関する情報を取得するクラスです．通常のゲームオブジェクトをスクリプトから取得するためには多少手間がかかるのですが，カメラはこれにより簡単に操作できるようになります．

### `private MLInput.Controller _controller;`
コントローラの情報を取得するためのクラスです．詳細については調べ次第書きます．

### `void start()`
Startメソッドは特別なものでこのスクリプトが実行されたときに最初に1回のみ実行されます．

### `MLInput.Start();`
これによりmagicleapの入力が開始されます．

### `_controller = MLInput.GetController(MLInput.Hand.Left);`
これにより左側のコントローラーを選択して入力を受け取ることができるようになりました．

### `void OnDestroy()`
これもStartメソッドと同様に特殊なメソッドです．このスクリプトが登録されているゲームオブジェクトが破棄されたときに実行されます．

### `MLInput.Stop();`
これによりmagicleapの入力が終了されます．

### `void Update()`
これも特殊なメソッドで，unityの画面が更新されるごとに実行されるメソッドです．

### `updateTransform();`
後から宣言されているクラスをUpdateの中で実行するようにしています．ここで内容についても書いておきます．

#### `float speed = Time.deltaTime * 5.0f;`
`Time.dealtime`は1プレームにかかった時間を取得します．これに数値をかけることで時間を設定しています．
#### `Vector3 pos = Camera.transform.position + Camera.transform.forward;`
3次元のベクトルを用意して，その中にcameraの位置情報に「cameraの位置を原点にしてz方向に1進んだ位置情報」を加えています．平たく言うと前に1だけcameraが進んだ座標を入手ました．

#### `gameObject.transform.position = Vector3.SlerpUnclamped(gameObject.transform.position, pos, speed);`
ゲームオブジェクトの位置情報を取得して，2点間を球面補完する関数のようです．補間とは2点間を滑らかにつなぐこです．今回はgameObjectの位置からposに格納されたcameraの位置まで向かう道を作っています．特に今回は球面補間なので直線ではなく，球面に沿うような道が作られます．[Unity Vectorを一通り理解する](https://qiita.com/ShirakawaMaru/items/b2c19764c7971d1e1550)，[ベクトルの線形補間について](http://uchinoinu.hatenablog.jp/entry/2016/12/21/164118)あたりを読んでいただけるとよりわかると思います．

#### `Quaternion rot = Quaternion.LookRotation(gameObject.transform.position - Camera.transform.position);`
Quaternionはゲームオブジェクトの回転を扱うクラスです．詳しい内容は「[クォータニオン (Quaternion) を総整理！ ～ 三次元物体の回転と姿勢を鮮やかに扱う ～](https://qiita.com/drken/items/0639cf34cce14e8d58a5)」をみると参考になると思います．特に，Quaternion.LookRotationはある方向を向かせるためのQuaternionを作成することができます．引数に向きたい方向を取ります．今回はcameraから見たgameObjectの方向を向かせています．

他にもゲームオブジェクトにある方向を向かせる方法はありますが，急にその方向を向くことになります．この方法だとゆっくりその方向を向かせることができます．

#### `gameObject.transform.rotation = Quaternion.Slerp(gameObject.transform.rotation, rot, speed);`
このメソッドではgameObjectのQuaternion値を変更しています．引数に(変更前の値，変更後の値，定数)を取ります．この関数は変更前のQuaternion値から変更後のQuaternion値まで定数の分だけ近づける機能があります．定数は０から１までの値が入力できて1に近づくほど変更後のQuaternion値の値に，0近づくほどQuaternion値に近づきます．

### `updateGestureText();`
上と同様にあとから宣言されているクラスをUpdateの中で十個するようにしています．ここで内容についても書いておきます．

#### `string gestureType = _controller.CurrentTouchpadGesture.Type.ToString();`
stringは文字列を扱う変数です．これは入力されたジェスチャーを表示するために用意しています．`Tostring`はintやfloatなどの数字を文字列に変換する関数です．左側のコントローラーの入力を受けた`_controller`から状態を入手して代入しています．

以前のバージョンのnamespaceであると思われるカンファレンスを見つけたので，「[Enum MagicLeapInputControllerTouchpadGestureType](https://docs.unity3d.com/Packages/com.unity.xr.magicleap@6.0/api/UnityEngine.XR.MagicLeap.MagicLeapInputControllerTouchpadGestureType.html)」を参考にしました．

これ以降の2行も同様の内容なので省略します．

#### `typeText.text = "Type: " + gestureType;`
unity上で表示するために用意したテキストに文字列を代入します．複数の文字列を代入するときは`+`でつなぐことができます．


# まとめ
以上が今回自分が調べた内容です．素人が調べた内容なので正しい情報がであることは証明できませんが，これからも内容に修正する部分を見つけ次第修正しておきます．また，内容に間違いがありましたらコメントいただけると幸いです．




#　参考にしたもの
1. [#regionを使わないほうがよい３つの理由と１つの例外](https://qiita.com/mono1729/items/f2a19724ff654b2556d8)
2. [3分でわかる！Unityのテキスト（text）の内容を変更する方法](https://freesworder.net/unity-text-change/)
3. [【Unity入門】カメラの基礎を学ぼう!あんな挙動も意外と簡単!?](https://www.sejuku.net/blog/55071)
4. [【Unity】Magic Leap でコントローラーからのボタン入力を取得する](https://pieslog.hatenablog.com/entry/2019/11/11/233137)
5. [UnityスクリプトカンファレンスVector3](https://docs.unity3d.com/ja/current/ScriptReference/Vector3.html)
6. [【Unity】ベクトルと回転備忘録](https://qiita.com/Nekomasu/items/a7459a32adb4770d81c8)
7. [Unity Vectorを一通り理解する](https://qiita.com/ShirakawaMaru/items/b2c19764c7971d1e1550)
8. [ベクトルの線形補間について](http://uchinoinu.hatenablog.jp/entry/2016/12/21/164118)
9. [クォータニオン (Quaternion) を総整理！ ～ 三次元物体の回転と姿勢を鮮やかに扱う ～](https://qiita.com/drken/items/0639cf34cce14e8d58a5)
10. [Quaternion.Slerp() についての解説](http://nakamura001.hatenablog.com/entry/20110705/1309890918)
11. [【Unity】文字列stringの関数まとめ](https://squmarigames.com/2018/11/18/unity-string-summary/)
12. [Enum MagicLeapInputControllerTouchpadGestureType](https://docs.unity3d.com/Packages/com.unity.xr.magicleap@6.0/api/UnityEngine.XR.MagicLeap.MagicLeapInputControllerTouchpadGestureType.html)