UnityでSwitchのジョイコンの入力情報を取得する

#はじめに

PCとSwitchのジョイコンを接続してコントローラを操作した場合に、Unityではどのようなキーが入力されるのか、以下の記事を参考に調べてみました。

PCとジョイコンを接続する方法は下記の記事を参考にしました。（記事中ではプロコンで説明）
https://kirbystar10423816.hatenablog.com/entry/2019/05/18/224953

Unity上でコントローラの入力値を取得する方法は下記の記事を参考にしました。
https://qiita.com/pilkul/items/6351a967372541d92718

##結果

結果は以下のとおりです。

|Switch|Unity|
|:-:|:-:|
|A|JoystickButton0|
|B|JoystickButton2|
|X|JoystickButton1|
|Y|JoystickButton3|
|十字↑|JoystickButton2|
|十字→|JoystickButton3|
|十字↓|JoystickButton1|
|十字←|JoystickButton0|
|Lスティック|JoystickButton10|
|Rスティック|JoystickButton11|
|L|JoystickButton14|
|R|JoystickButton14|
|ZL|JoystickButton15|
|ZR|JoystickButton15|
|左SL|JoystickButton4|
|左SR|JoystickButton5|
|右SL|JoystickButton5|
|右SR|JoystickButton4|
|-|JoystickButton8|
|+|JoystickButton9|
|HOME|JoystickButton12|
|キャプチャ|JoystickButton13|

##説明

ABXYと十字キー、LとR、ZLとZR、それぞれのSL、SRの入力で取得できる値がかぶっています。
なぜこのような値が入力されるのかというと、ジョイコンの左半分と右半分が別々のデバイスとして認識されているためです。

下記の記事のように、コントローラが１つのデバイスとして認識されるプロコンであれば、このようなことは発生しないと考えられます（デバイスを所有していないので未検証）
https://qiita.com/Sadmachine/items/c3b62e01f656d1f774ee

#一意のボタンとして判定するには

左右で重複しているKeyCodeのボタンを、一意のボタンとして認識するには、下記のコードで押下を判定することで可能です。（例としてJoystickButton0として判定された右のAボタン、左の十字←ボタンの押下を一意に判定）

```csharp:SwitchInput.cs
using System.Collections.Generic;
using UnityEngine;
public class SwitchInput : MonoBehaviour
{
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Joystick1Button0)) Debug.Log("test_Right");  //Right
        if(Input.GetKeyDown(KeyCode.Joystick2Button0)) Debug.Log("test_Left");  //Left
        if(Input.GetKeyDown(KeyCode.JoystickButton0)) Debug.Log("test");  //common
    }
}
```

上記のコードを実行して検証すると、右のAボタンを押下したときに、Consoleにtest_Rightとtestが表示され、左の十字←を押下したときには、test_Leftとtestが表示されます。

前述した下記の記事で、同様の判定を行うには、DownKeyCheck関数のforeach内のbreak文を削除することで実装することが可能です。（一意のKeyCodeを出力する場合は、foreach内で取得したKeyCodeをキャッシュして、値の大きい方のKeyCodeを出力するなどで実装可能）
https://qiita.com/pilkul/items/6351a967372541d92718

なぜこのようなことが発生するかというと、一つのボタンに複数のKeyCodeが割り当てられているためです。break文があることで、１つのキーを判定した時点で処理を中断してしまうので、ボタンに割り当てられた全てのKeyCodeを表示することが可能です。

##結果

上記のことを踏まえて取得した結果を、以下に記載します。

| Switch | Unity |
|:------------:|:----------------:|
|A|Joystick1Button0|
|B|Joystick1Button2|
|X|Joystick1Button1|
|Y|Joystick1Button3|
|十字↑|Joystick2Button2|
|十字→|Joystick2Button3|
|十字↓|Joystick2Button1|
|十字←|Joystick2Button0|
|Lスティック|Joystick2Button10|
|Rスティック|Joystick1Button11|
|L|Joystick2Button14|
|R|Joystick1Button14|
|ZL|Joystick2Button15|
|ZR|Joystick1Button15|
|左SL|Joystick2Button4|
|左SR|Joystick2Button5|
|右SL|Joystick1Button5|
|右SR|Joystick1Button4|
|-|Joystick2Button8|
|+|Joystick1Button9|
|HOME|Joystick1Button12|
|キャプチャ|Joystick2Button13|

KeyCodeについての参考記事
https://docs.unity3d.com/ja/2019.4/ScriptReference/KeyCode.html

任天堂の公式サイトのジョイコンの画像を引用して結果を記載します。
https://www.nintendo.co.jp/hardware/detail/switch/index.html#3

![body-switch03-front_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147257/da8453d4-f3f2-eb7c-14a2-6a534ac43ae6.png)

![body-switch03-side_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147257/8e70a253-8307-f9a5-5e1e-8a26d69f21c0.png)

##コントローラのボタン押下のテスター
上記の結果を踏まえて、スイッチのジョイコンの任意のキーが押されているか表示するプログラムを書いてみました。

```csharp:SwitchInput.cs
using System.Collections.Generic;
using UnityEngine;
using System;
public class SwitchInput : MonoBehaviour
{
    void Update()
    {
        SwitchControllerAnyKeyDown();
    }

    private void SwitchControllerAnyKeyDown(){
        if (Input.anyKeyDown) {
            foreach (SwitchController code in Enum.GetValues(typeof(SwitchController))) {
                if (Input.GetKeyDown ((KeyCode)code)) Debug.Log(code);
            }
        }
    }
}

public enum SwitchController{
    A = 350,
    B = 352,
    X = 351,
    Y = 353,
    UpArrow = 372,
    LeftArrow = 370,
    RightArrow = 373,
    DownArrow = 371,
    LStick = 380,
    RStick = 361,
    L = 384,
    R = 364,
    ZL = 385,
    ZR = 365,
    LeftSL = 374,
    LeftSR = 375,
    RightSL = 354,
    RightSR = 355,
    Minus = 378,
    Plus = 359,
    HOME = 362,
    Capture = 383 
}
```


##参考記事

記事を書くにあたって参考にした記事を紹介します。（本文中でも紹介しています）

[PCでSwitchのプロコンを使って快適にゲームする話]
(https://kirbystar10423816.hatenablog.com/entry/2019/05/18/224953)

[Unity - 入力されたキーの情報を取得する]
(https://qiita.com/pilkul/items/6351a967372541d92718)

[Unity Documentation KeyCode（Unityスクリプトリファレンス）]
(https://docs.unity3d.com/ja/2019.4/ScriptReference/KeyCode.html)

##追記

2021年8月23日
・PCのとジョイコンの左右を接続する順番によって、Joystick1とJoystick2が入れ替わるので、この記事を参考にする場合は先に右側のコントローラをPCとペアリングしてください。先に左側のコントローラをペアリングした場合は、Joystick1とJoystick2を入れ替えて呼んでください。
・この記事を投稿したあとに、以下の記事を見つけました。GithubのJoiconLibというリポジトリのアセットを使用してJoyconのボタン入力だけでなく、センサの値も取得できます。参考までに。
[Nintendo SwitchのJoy-Conを使ってユニティちゃんの腕を動かす](https://qiita.com/fuloru169/items/54cbb3571d389aa074f7)
[該当リポジトリ:Github Looking-Glass/JoyconLib](https://github.com/Looking-Glass/JoyconLib)