Hiromuブログ

最近はこちら(https://zenn.dev/hiromu)が本体

Joy-Conと女子高生とSpatialUnderstandingと

Nintendo SwitchJoy-ConをHoloLensで利用してみたのでその内容をまとめました。

Joy-Con

UnityでJoy-Conを利用する方法についてはすでにいくつかブログで紹介されているのでそちらが参考になります。

その中で個人的に分かりやすいと感じたサイトは【Unity】Nintendo Switch の Joy-Con を使用する方法 です。


HoloLensで利用する場合は以下画像にあるPlayer Settings –> Capabilitiesの[HumanInterfaceDevice]と[Bluetooth]にチェックを入れます。

joy-con01


以下画像にある、ボタンのJoystick番号については各環境により異なる値になるため注意が必要です。

joy-con02


以上の設定が済めばあとは以下のようなコードで動作を確認できます。全ボタンをアサインしたので興味がればご自由にご利用ください。ただしアナログスティックについてはHoloLens実機上では正しい値はとれませんでした。

※Joystick番号は上述の通り適宜修正してください、またDebug.Logはエディタ上でしか表示されないため実機で何かしら表示する場合はTextMesh等を配置してください

using UnityEngine;

/// 
/// Nintendo SwitchJoy-Conのインプットサンプル
/// 
public class JoyConSample : MonoBehaviour
{
    void Update()
    {
        #region Joy-Con(R)
        // axisNameはInputManagerで設定した名前にする
        var hR = Input.GetAxis("Joy-Con(R) Horizontal");
        var vR = Input.GetAxis("Joy-Con(R) Vertical");
        if (hR != 0 || vR != 0)
        {
            Debug.LogFormat("Joy-Con(R) : H({0}), V({1})", hR, vR);
        }

        // KeyCode.Joystick「番号」は各自の環境に合わせた番号にする
        if (Input.GetKeyDown(KeyCode.Joystick3Button0))
        {
            Debug.Log("A");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button2))
        {
            Debug.Log("B");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button1))
        {
            Debug.Log("X");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button3))
        {
            Debug.Log("Y");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button14))
        {
            Debug.Log("R");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button15))
        {
            Debug.Log("ZR");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button5))
        {
            Debug.Log("SR");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button4))
        {
            Debug.Log("SL");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button9))
        {
            Debug.Log("+");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button12))
        {
            Debug.Log("HOME");
        }

        if (Input.GetKeyDown(KeyCode.Joystick3Button11))
        {
            Debug.Log("R Stick");
        }
        #endregion

        #region Joy-Con(L)
        var hL = Input.GetAxis("Joy-Con(L) Horizontal");
        var vL = Input.GetAxis("Joy-Con(L) Vertical");

        if (hL != 0 || vL != 0)
        {
            Debug.LogFormat("Joy-Con(L) : H({0}), V({1})", hL, vL);
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button2))
        {
            Debug.Log("UP");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button3))
        {
            Debug.Log("RIGHT");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button1))
        {
            Debug.Log("DOWN");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button0))
        {
            Debug.Log("LEFT");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button14))
        {
            Debug.Log("L");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button15))
        {
            Debug.Log("ZL");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button5))
        {
            Debug.Log("SR");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button4))
        {
            Debug.Log("SL");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button8))
        {
            Debug.Log("-");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button13))
        {
            Debug.Log("CAPTURE");
        }

        if (Input.GetKeyDown(KeyCode.Joystick2Button10))
        {
            Debug.Log("L Stick");
        }
        #endregion
    }
}


モデルデータ

女子高生アセットはセールのときに$0.83だったのでうっかり買ったものです。

Fighter - School Girl

school_giel


SpatialUnderstanding

SpatialUnderstandingで注意が必要な点として以下の動画のような点があります。

いきなりシーンにオブジェクトを配置してしまうとまだメッシュが生成されていないため落下してしまいます。そのため、メッシュが生成されてからオブジェクトを生成するなり位置を調整する必要があります。

これを実現する方法として以下手順を踏む必要があります。

  • スキャンが終了したときに呼ばれるコールバックを設定する
  • スキャンが終了したことをアプリケーション側の任意のタイミングで設定する
  • コールバック内でオブジェクトの生成等を行う

具体的には以下のようなコードになります。サンプルでは5秒経過したらスキャンが終了したものとみなして位置を再設定しています。

using System.Collections;
using UnityEngine;
using HoloToolkit.Unity;

public class GameInitializer : MonoBehaviour {
    public TextMesh textMesh;
    public GameObject girl;

    void Start () {
        textMesh.text = "Start scanning.";

        // スキャン終了時に呼ばれるコールバックにInitializeメソッドを設定する
        SpatialUnderstanding.Instance.OnScanDone += Initialize;

        // 5秒間待つコルーンチを開始する
        StartCoroutine(ScanWaitCoroutine());
    }

    IEnumerator ScanWaitCoroutine()
    {
        // 5秒待つ
        textMesh.text = "Now scanning ...";
        yield return new WaitForSeconds(5f);

        // 5秒経過したらスキャン終了と見なす
        textMesh.text = "Scan finished.";
        SpatialUnderstanding.Instance.RequestFinishScan();
    }

    void Initialize()
    {
        // スキャン終了後の初期化処理等
        textMesh.gameObject.SetActive(false);
        girl.transform.position = new Vector3(0f, 0f, 2f);
    }
}