Viveの入力をActionで扱い、コードを綺麗にする話

この記事は最終更新日から3年以上が経過しています。

はじめに

HTC Viveは様々な入力方法があるし、Unityでは扱いやすいのでいろいろ想像が膨らんで楽しいですね!

ただ普通にコード書くと例えば以下のようなコードを書きがちです。

tmp.cs
    void Update()
    {
        SteamVR_TrackedObject trackedObject = con.GetComponent<SteamVR_TrackedObject>();

        var device = SteamVR_Controller.Input((int)trackedObject.index);

        if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger))
        {
                //Viveでトリガーを押した時に何か処理をする
        }
    }

流石にtrackedObjectはStart()で宣言するだけに留めるにしても、
その宣言やif(device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger))なんてことはいちいちクラス毎に書いてられません。

なので、今回はViveの入力をEventで扱うクラスを作って各クラスでそれを利用しましょうという話です。

入力をEventで扱うクラス書く

今回は左コントローラのEventHandlerを書きましょう

LeftViveControllerHandler.cs
using UnityEngine;
using System.Collections;
using System;
public class LeftViveControllerHandler : MonoBehaviour
{
    public SteamVR_TrackedObject trackedObject { get; set; }
    public SteamVR_Controller.Device device { get; set; }

    public static Action GripButton_Pressed();
    public static Action Trigger_SharrowPressed();
    public static Action Trigger_DeepPressed();
    public static Action Trigger_Released();
    public static Action TouchPad_Pressed();
    public static Action TouchPad_Pressing();
    public static Action TouchPad_Released();
    public static Action TouchPad_TouchDown();
    public static Action TouchPad_Touching();
    public static Action TouchPad_TouchUp();
    public static Action MenuButton_Pressed();

    void Start()
    {
        trackedObject = GetComponent<SteamVR_TrackedObject>();
        device = SteamVR_Controller.Input((int)trackedObject.index);
    }
    void Update()
    {
        if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger))
        {
            Trigger_SharrowPressed();
        }
        if (device.GetPressDown(SteamVR_Controller.ButtonMask.Trigger))
        {
            Trigger_DeepPressed();
        }
        if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger))
        {
            Trigger_Released();
        }
        if (device.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_Pressed();
        }
        if (device.GetPress(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_Touching();
        }
        if (device.GetPressUp(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_Released();
        }
        if (device.GetTouch(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_Touching();
        }
        if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_TouchDown();
        }
        if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Touchpad))
        {
            TouchPad_TouchUp();
        }
        if (device.GetPressDown(SteamVR_Controller.ButtonMask.ApplicationMenu))
        {
            MenuButton_Pressed();
        }
        if (device.GetPressDown(SteamVR_Controller.ButtonMask.Grip))
        {
            GripButton_Pressed();
        }
    }
}

Viveで何かしら入力を行うとそれに対応したEventメソッドが発火するようになっています。

利用する

MenuManager.cs
using UnityEngine;
using System.Collections;

public class MenuManager : MonoBehaviour
{
    void Start()
    {
        LeftViveControllerHandler.GripButton_Pressed += DoSomethingOnGripButton_Pressed;
    }

    void DoSomethingOnGripButton_Pressed() {
        //グリップボタンが押されたときの処理を書く
    }

}

例えばこのコードなら、ViveのGripButtonをクリックした時の処理をStart()で登録しています。
その処理では、子要素をEnableにしたりDisableにしたりします。
普通にやると最初に書いたようにUpdate()作ってそこにif文を書くと思うのですが、それに比べれば軽量でスリムなコードが書けると思います。

今回はたまたまViveの話でしたが、例えばInput.KeyDownとかもEventとして扱いたい時は同様に入力を扱うクラスを作れば良いので、割と使いまわせる概念だと思います。以上です。

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした