Unity2DのチュートリアルをInputSystemに書き換える(2)

[前](https://qiita.com/DiveMasakazu/items/6de1e9261e251d8ce57c)

ワク　チン
　ワク　チン
で熱出たり
釣り行ったり、ライブ行ったり、飲みに行ったりしていたら前回から時間経ってしまった

## Fire
前回はRubyをInput Systemを使って前後左右に動かすところまでやった。
`inputAction.Player.Move.ReadValue<Vector2>();`
でジョイスティックやキーボードのXYが取れたけど、ではABボタンはというと
`testInputActions.Player.Fire.performed += context => Debug.Log("Fire");`
がサンプルとして書いてある。
これは十字キーと違ってUpdateで取って処理するパターンではない・・・
ので[ドキュメント](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/api/UnityEngine.InputSystem.PlayerInput.html)を見てみると
` if (m_PlayerInput.actions["fire"].triggered)`
こんな感じで押されているかの判定は出来そう。
旧タイプの場合は`Input.GetButtonDown`で抑え始めた次のフレームで取得されるような感じだったけど、
新タイプは他に方法があるのかいまいち分からないので調べていると
[新旧のメソッド比較](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Migration.html?q=WasReleasedThisFrame)みたいなのが公式で存在した。

 * Input.GetButton = ButtonControl.isPressed 
 * input.GetButtonDown = ButtonControl.wasPressedThisFrame 
 * input.GetButtonUp = ButtonControl.wasReleasedThisFrame

とはいえ、triggeredも連射するわけでなく、次のフレームで発火するみたいなのと、
Fireに対して十字キーのように`inputAction.Player.Fire.ReadValue<float>()`
で押しっぱなしかを取れるので大きな問題はなさそう。

```
//if(Input.GetButtonDown("Fire1")){
if(inputAction.Player.Fire.triggered){
    Launch();
}
```

ついでにZボタンをFireに割り当ててみたらちゃんと動いた。
ただ、Zを割り当てる時にキーボード/マウスにフィルターかけないと拾ってくれなかったので、
仕様なのかまで調べていないが、うまくいかない時はフィルターをすれば良さそう。


## バーチャルコントローラー

ここからスマホ対応の話
スマホ用のバーチャルコントローラーも用意されていて、インポートすれば使える。

その前に対応デバイスにマウスとタッチデバイスを追加した。

というのは分かった。
Input Systemのタッチ関係で上下左右（スライドさせて）出来ないのかは書いてないので調べる。
なにやらDeltaとかRadiusとかの項目がある。
ポジションの位置とか差を取得可能っぽい。
最初のタップ位置(fire)からスライドさせた距離から十字を作成、とかすればいいのかな。
ダブルタップの取得が出来るのかがこれだけだと分からなかったが
InteractionsにMultiTapというのがある。
[ドキュメント](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.1/manual/Interactions.html)上では
'A MultiTapInteraction requires the user to press and release a Control within tapTime seconds tapCount times, with no more then tapDelay seconds passing between taps, for the Interaction to trigger. You can use this to detect double-click or multi-click gestures.'
と書いてある。

PressのReleaseOnlyで試すと、確かにボタンを離した時にイベントが発生する。
が、MultiTapにしてもマウスだと反応してくれない・・・
海外のフォーラムだと去年バグではないかという話もしているが
ここでいくつかテスト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/bb94f007-4ecf-60bc-64e0-cc694144fbce.png)


* Fireの中身をLeftClickだけにして、Fireに対してマルチタップ設定⇒ダブルクリック動いた
* FIreからマルチタップを外して、LeftClickにマルチタップ⇒ダブルクリック動いた
* FireにキーボードのZを追加⇒ダブルクリック動かない
* Zを削除して、タップ（プライマリ）を追加⇒ダブルクリック動いた

なので、現象だけ見るとkeybord/mouseが複数個存在している場合はmultiTapは上手く動作しない
という事なのかもしれない。

普通に単純にマウスクリックとかタップについてはこれで使えそう。

## タッチ入力を取得する

EnhancedTouchを使ってタッチ動作をキャプチャする。
だがPCのディスプレイはタッチデバイスではないで、機種変でいらなくなった前のXperiaを利用して確認。
（開発者モードで繋いでもビルド設定に出なかったが、Unity再起動したら選択できた）
あと[ここ](https://myudon.hatenablog.com/entry/2021/02/01/234545)見ると
`EnhancedTouchはInputSystemで入力のイベント処理を実装するための機能であるInputActionと併用ができないそうです`
とあるが、サポートを有効にすると使えなくなるのかテスト

```
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;

void Awake(){
    inputAction = new PlayerInput();
    inputAction.Enable();
    EnhancedTouchSupport.Enable();
}
```

コンパイルエラーは起きる気配はないし、普通に先ほどのダブルクリックも動作した。とりあえずこの範囲だと問題ないような雰囲気。

サンプル見るとforeachで回してるけど、これは複数タッチが出来るという意味っぽいので

```
 foreach (var touch in Touch.activeTouches)
    {
        text += $"Touch: Id {touch.touchId} Position {touch.screenPosition} Phase {touch.phase}\n";
    }
```

[ここ](https://gentome.com/gentomeblog/2989/unityandroidlogcat/)見ながらAndroid LogCatを入れて確認。
タッチIDが何か分からないので、1本目の指のタッチだけ取れたらいいのでiDは0なのかと思ってたが、
IDは起動してから1からどんどん増えていっていた。
なお、スマホの画面（カメラ）がうまくいってなかったが、今回やりたい事ではないので一旦無視。

次回は弓を引く感じでRubyが弾を発射できないか、試してみる予定