[Unity]Nintendo SwitchのJoy-Conを使って方向誘導

この記事は[リンク情報システム](https://www.lis.co.jp/)の2018年アドベントカレンダーのリレー記事です。
engineer.hanzomon のグループメンバによってリレーされます。
（リンク情報システムのFacebookは[こちらから](https://www.facebook.com/lis.co.jp)）


#はじめに
17日目担当の120600mahです。よろしくお願いします！
今回はNintendo SwitchのJoy-ConのHD振動の性能を検証するという内容です。

![Joy-Con](https://qiita-image-store.s3.amazonaws.com/0/314337/1f64fe9b-721b-72f9-6993-0262950fc531.jpeg)


Joy-ConとはNintendo Switchに付属しているコントローラーです。
Joy-Conには「ジャイロセンサー」、「加速度センサー」、
「モーションIRカメラ」、「HD振動」という機能があります。
その中で、微細な振動で細かい表現のできる[HD振動](https://topics.nintendo.co.jp/c/article/73d9531a-6bbe-11e7-8cda-063b7ac45a6d.html
)を使ってみようと思います。

HD振動を使って何をしようか考えていたところ、
大学のときにVRの研究をしていたので、
振動と言うと触覚に関するVR技術が頭に浮かびました。
そのときに気になっていたVRの手法として、
「加速度での牽引力」というものがあります。

引っ張りたい方向を「短い時間の大きな加速度」にして、
反対方向を「長い時間の小さな加速度」とします。
この２つの動きを連続で繰り返すことで、
指定した方向に引っ張られてるという感覚を与えるというものです。

なんとなく仕組みは理解できますが、
本当に引っ張られている感覚を得られるのか疑問に感じていました。

そこで、今まで疑問に感じていた加速度での牽引力を
Joy-Conの振動機能を使って表現してみたいと思います。



#検証環境
・Unity 2018.2.18
・macOS Sierra 10.12.6

参考ページ
http://baba-s.hatenablog.com/entry/2017/10/24/130000
http://baba-s.hatenablog.com/entry/2017/11/12/090000

#動作確認
まずは、参考ページを参考にJoy-ConをUnityで使えるようにします。
それから以下のコードを作成してGameObjectにアタッチします。

Joy-Conは左のみを使用にしました。
キーボードの「W」で前方向、「S」で後ろ方向に力が発生します。

```c#:Direct.cs
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine;

public class Direct : MonoBehaviour
{
    private List<Joycon> m_joycons;
    private Joycon m_joyconL;

    private void Start()
    {
        m_joycons = JoyconManager.Instance.j;

        if (m_joycons == null || m_joycons.Count <= 0) return;

        m_joyconL = m_joycons.Find(c => c.isLeft);
    }

    private void Update()
    {
        if (m_joycons == null || m_joycons.Count <= 0) return;

        if (Input.GetKeyDown(KeyCode.W))
        {
            StartCoroutine("Forward");
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            StartCoroutine("Back");
        }
    }

    IEnumerator Forward()
    {
        for (int i = 0; i < 5; i++)
        {
            m_joyconL.SetRumble(0, -500.0f, 1.0f, 20);
            yield return new WaitForSeconds(0.02f);
            m_joyconL.SetRumble(0, 1.0f, 0.2f, 50);
            yield return new WaitForSeconds(0.05f);
        }
    }

    IEnumerator Back()
    {
        for (int i = 0; i < 5; i++)
        {
            m_joyconL.SetRumble(0, 500.0f, 1.0f, 20);
            yield return new WaitForSeconds(0.02f);
            m_joyconL.SetRumble(0, -1.0f, 0.2f, 50);
            yield return new WaitForSeconds(0.05f);
        }
    }


    private void OnGUI()
    {
        var style = GUI.skin.GetStyle("label");
        style.fontSize = 24;

        if (m_joycons == null || m_joycons.Count <= 0)
        {
            GUILayout.Label("Joy-Con が接続されていません");
            return;
        }

        if (!m_joycons.Any(c => c.isLeft))
        {
            GUILayout.Label("Joy-Con (L) が接続されていません");
            return;
        }
    }
}
```
　

結果は…前後に誘導されている感覚を得ることができました！

色々試してみましたが、この設定が前と後ろの判断がしやすかったです。
誘導するような映像も合わせて作ればもっとリアルにできるのではないかと思います。

#感想
Nintendo Switchを買ってから一度も使っていなかった
Joy-Conが日の目を見ることが出来てよかったです。
据え置きゲームのコントローラーで
自由度の高い振動表現ができることに驚きました！
今回はJoy-Conの「HD振動」を試してみましたが、
「モーションIRカメラ」で手の動きなど読み取れるみたいなので気になります。

お読みいただきありがとうございました！
明日は@h-yamasakiさんです！