VRTKを使ってViveコントローラの入力を取り扱う

投稿者: | 2016-12-13

HTC Viveでのアプリ開発方法を調べていたところ、VRTKというアセットを見つけました。色々サンプルも用意されているので試してみたところ、オブジェクトを掴む、テレポート移動する、といったVRアプリでよくみられる機能はノンコーディングで実装できることがわかり、これはかなり便利そうだと思いました。実際にビルの上に橋をかけて渡るといったザ・ウォーク体験ができる簡単なアプリを作ってみたのですが、VRTKを使ったところ数十行程度コードを書くだけで出来てしまいました。そこで今回はVRTKの導入方法と、一番基本となるVRTKを使用してコントローラからの入力を取り扱う方法をまとめたいと思います。

VRTKの導入

VRTKとは

VRTKはUnityでHTC Vive用VRアプリを開発する際に有用なスクリプトやプレファブを集めたツールキットです。現時点の対応プラットフォームはHTC Viveのみであり、SteamVR Pluginに依存した無料アセットです。サンプルも豊富に用意されており、動画による解説も充実しているので、理解しやすいと思います。

VRTKの導入

アセットストアにてSteamVR PluginVRTKをダウンロードし、インポートすれば完了です。

サンプルを試してみる

サンプルシーンが/フォルダ名/に入っていますので試してみてください。なお、公式ページに簡単な説明と動画へのリンクが貼ってありますので、そちらもかなり参考になるかと思います。

各サンプルのVRTK以外のコードを見れば、スクリプトの使い方もわかってくると思います。

VRTKを使ってコントローラからの入力を取り扱う

それではVRTKを使って簡単なサンプルを作りたいと思います。内容は前回の記事のサンプルを一部流用して、Viveコントローラのトリガーを引くとCubeが破裂する、といったものです。

サンプルの実装

まずはSteamVR PluginのSteamVR/Prefabs/[CameraRig]をシーンに追加します。この時点でアプリケーションのVR化は完了しているので、HTC Viveを起動した状態でアプリの再生を行うと、HMDに映像が出力され空間上にViveコントローラが現れます。
続いて、追加した[CameraRig]配下にコントローラオブジェクトがありますので、そちらにVRTK/Scripts/VRTK_ControllerEventsをアタッチします。

このスクリプトをアタッチするだけでViveコントローラの各種ボタンを押すとイベントが発行されるようになります。あとはイベントハンドラを用意し、各種ボタン操作に応じたイベントに登録すれば完成です。
シーンには前回同様、PlaneとCubeを配置します。今回はCubeに”target”というタグを新規に作成して割り当てます。イベントハンドラの内容と、イベントの登録のコードは以下の通りです。

using UnityEngine;
using VRTK;

public class ControllerEventTest : MonoBehaviour
{
    private void OnEnable()
    {
        if (GetComponent<VRTK_ControllerEvents>() == null)
            return;
        // イベントハンドラの登録
        GetComponent<VRTK_ControllerEvents>().TriggerPressed += TriggerPressedHandler;
    }

    private void OnDisable()
    {
        if (GetComponent<VRTK_ControllerEvents>() == null)
            return;
        // イベントハンドラの解除
        GetComponent<VRTK_ControllerEvents>().TriggerPressed -= TriggerPressedHandler;
    }

    // イベントハンドラ
    private void TriggerPressedHandler(object sender, ControllerInteractionEventArgs e)
    {
        GameObject[] targets = GameObject.FindGameObjectsWithTag("target");
        foreach(var target in targets)
        {
            if(target.transform.localScale.x > 0.05f)
            {
                Color color = new Color(Random.value, Random.value, Random.value);
                for (int i = 0; i < directions.Length; i++) {
                    var obj = Instantiate(target);
                    var cube = obj.transform;
                    cube.name = "Cube";
                    cube.localScale = 0.5f * target.transform.localScale;
                    cube.position = target.transform.TransformPoint(directions[i] / 4);
                    cube.GetComponent<Rigidbody>()
                        .AddForce(10.0f * Random.insideUnitSphere, ForceMode.VelocityChange);
                    cube.GetComponent<Renderer>().material.color = color;
                }
                Destroy(target);
            }
        }
    }

    private Vector3[] directions =
    {
        new Vector3(1,-1,1),
        new Vector3(-1,-1,1),
        new Vector3(-1,-1,-1),
        new Vector3(1,-1,-1),
        new Vector3(1,1,1),
        new Vector3(-1,1,1),
        new Vector3(-1,1,-1),
        new Vector3(1,1,-1),
    };
}

このスクリプトをコントローラオブジェクトにアタッチします。
アプリを起動してトリガーボタンを押すと、Cubeがはじける様子が確認できると思います。

8倍ずつCubeが増えていくのでハジケすぎると落ちます。。。
なんの工夫もないコードですが、ハジケる様はなかなかシュールで面白いです。

インスペクタで設定できるパラメータについて

VRTK_ControllerEventsにはインスペクタ上から設定できる項目がいくつか存在しますが、リストボックスで設定できるのはVRTKで定義されているアクションに割り当てるボタンです。

VRTKではVRアプリでよく使うであろう、物を掴むだとか、コントローラからポインタを出すといった動作を、内部でイベント変数として定義しています。そのようなVRTKで定義されている動作を、Viveコントローラのどのボタンで実施するかを設定できるのがこの項目です。

例えば「Pointer Toggle Button」はデフォルトではTouchpad_pressが設定されています。このときVRTK_SimplePointerをコントローラオブジェクトにアタッチすると、タッチパッドを押し込んだ時にレーザーポインタが表示されます。ここで「Ponter Toggle Button」をGripに設定すると、以降はViveコントローラの側面にあるGripボタンを押したときにレーザーポインタが表示されるようになります。

このようにインスペクタではVRTK内部で定義されている動作を、どのボタンで制御するかを設定することができます。したがって、何か新しい動作を定義したい場合は、VRTK_ControllerEventsを参考に拡張すれば実現することができます。また、前述したとおり、内部で定義されている動作に紐づくイベント変数が、「AliasPointerOn」や「AliasGrabOn」のように用意されているので、こちらのイベント変数にハンドラを登録することによって、ボタン種別に依存せずにイベントハンドリングを設定することができます。

そのほか、float値を設定する項目については後述のリファレンスを参照してください。(すいません、一部は調査中です…)
スクリプトの解説は以上となります。

VRTKの日本語リファレンスを作り始めました

VRTKの日本語情報が少ししか見かけなかったなので、学習/調査結果のまとめも兼ねて日本語リファレンスを作り始めました。(Topのメニューバーからもアクセスできます)
翻訳を目指しているわけでは無いので、本家とは内容が一部異なるかもしれません。

まとめと今後

HTC Vive用VRアプリの開発をサポートしてくれるVRTKの導入方法と、Viveコントローラからの入力の取り扱い方法をまとめました。また、VRTKの日本語リファレンスとして、VRTK_ControllerEventsのリファレンスを作りました。これからはVRTKの使い方をさらに探りつつ、リファレンスを充実させていきたいと思います。