NO ENGINEER NO CRY

泣かないエンジニアはいない

【Unity】Magic Leap でコントローラーからのボタン入力を取得する

環境構築などはこちらを参考に
実機が無くてもシミュレータで動かせます

qiita.com

ボタンの説明

f:id:imln20:20191111153229j:plain

分かりにくいですが、こんな感じのコントローラーになっています

f:id:imln20:20191111153610j:plain

ボタンは全部で4つあり、TouchPad,Bumper,Triggerボタンがあります
完全に書き忘れなのですが、touchpadの手前にある丸っこいのがHomeTapボタンです

ボタンの取得

以下のスクリプトをキューブにアタッチすると、ボタンの入力に応じてキューブが動きます

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.MagicLeap;

public class cubeScript : MonoBehaviour
{
    public enum ButtonStates
    {
        Normal,
        Pressed,
        JustReleased
    };
    
    public ButtonStates BtnState;
    public bool isPressHome=false;
    private MLInputController _controller;

    // Start is called before the first frame update
    void Start()
    {
        // Start input
        MLInput.Start(); //入力取得開始
        MLInput.OnControllerButtonDown += HandleOnButtonDown; //ボタン押下に任意の関数を適用
        MLInput.OnControllerButtonUp += HandleOnButtonUp;  //ボタンから手を離したときに任意の関数を適用
        _controller = MLInput.GetController(MLInput.Hand.Left); //コントローラーを選択
    }

    // Update is called once per frame
    void Update()
    {
        if(BtnState == ButtonStates.Pressed)
        {
            this.transform.Translate(0.0f,0.1f,0.0f,Space.World);
        }
        
        TriggerButton();
        TouchPad();
    }

    void HandleOnButtonUp(byte controller_id, MLInputControllerButton button)
    {
        // Callback - Button Up
        if (button == MLInputControllerButton.Bumper)
        {
            BtnState = ButtonStates.JustReleased;
        }


        if (button == MLInputControllerButton.HomeTap)
        {
            isPressHome = false;
        }
    }

    void HandleOnButtonDown(byte controller_id, MLInputControllerButton button)
    {
        // Callback - Button Down
        if (button == MLInputControllerButton.Bumper)
        {
            BtnState = ButtonStates.Pressed;
        }

        if (button == MLInputControllerButton.HomeTap)
        {
            isPressHome = true;
            Debug.Log("test:" + isPressHome);
            this.transform.Translate(0.0f, 0.1f, 0.0f, Space.World);
        }
    }

    void TriggerButton()
    {
        if (_controller.TriggerValue >= 1.0f) //トリガーボタンの入力取得
        {
            this.transform.Translate(0.1f,0.0f,0.0f,Space.World);
        }
    }

    void TouchPad()
    {
        if (_controller.Touch1PosAndForce.z > 0.0f){ //押している間だけ
            float X = _controller.Touch1PosAndForce.x; //タッチパッドの位置取得
            this.transform.Translate(X, 0.0f, 0.0f, Space.World);
        }
    }
}

解説

見ての通りなのですが、まず起動時にInput.Startやコントローラの宣言を行っておく必要があるほか、ボタン押下時、押下終了時に関数を適用させるために MLInput.OnControllerButtonDown += HandleOnButtonDown; というようなコードを書く必要があります。
HandleOnButtonDown(...) では、押下されたボタンによって処理を変えることができます。
ただし、この関数で取得できるボタンは Bumper , HomeTap のみとなっており、残りの2つのボタンに関しては違う受け取り方をする必要があります。

TriggerButton() では、Triggerボタンの入力を取得しています。
ボタンの押し込み具合を0.0~1.0までの値で受け取ることができます。
ここでは
if (_controller.TriggerValue >= 1.0f)
という風にすることで、完全に押し込んだ時のみキューブが移動するようにしてあります。

TouchPad()では、TouchPadの入力を取得しています。
if (_controller.Touch1PosAndForce.z > 0.0f)
という条件は、「指がタッチパッドに触れている間」ということを意味します。この条件をなくすと、一度タッチパッドに触れると、指を離しても入力され続けてしまいます。
また、 _controller.Touch1PosAndForce.x により、触れているタッチパッドの位置を取得することができます。同じくy座標も取得できます。
このコードにより、真ん中より右側を触るとキューブが右側に、左側を触ると左側に移動するようになっています。