TouchScriptアセットのチュートリアルを試した

投稿者: | 2016-12-11

UnityにてAndroidやiOSの各種ジェスチャ操作を取り扱えるアセットを探していたところ、TouchScriptというアセットを見つけました。イベント駆動で動作し、イベントハンドラを用意し登録するだけで使うことができるので、しばらくはこちらを使ってアプリを作ろうと思います。なお、日本語記事が少ししか見当たらず、本家チュートリアルの内容も古かったので、そのあたりのフォローも含め本記事で導入部をまとめてみようと思います。

TouchScriptとは

TouchScriptはスマートフォン上の各種ジェスチャ操作を取り扱うことができるUnityの無料アセットです。クロスプラットフォームを謳っており、Android、iOS、Windows等環境を選びません。タップ、スワイプ、フリック等のジェスチャはあらかじめ用意されていますが、オリジナルのジェスチャを定義することもできます。

AsestStore

チュートリアルを試してみる

公式GitHubのWikiにいくつかのチュートリアルが用意されています。一番最初のタップジェスチャのチュートリアルが、基本的な使い方を学ぶのに最も適していると思います。

サンプル用に各種オブジェクトを用意する

シーン上にPlaneとCubeを配置します。CubeにはBoxColliderとRigidBodyをアタッチします。

TouchScriptの導入

AssetStoreからTouchScriptをダウンロードし、インポートします。

次に、空のGameObjectを配置し(名前をTouchScriptとしました)、TouchScript/Scripts/InputSources/StandardInputをアタッチします。

(チュートリアルにも書いてありますが、過去使用されていたMouseInputとMobileInputは現在は非推奨となっています)

また、必須ではありませんが、TouchScript/Prefabs/TouchVisualizerをシーンに追加すると、タッチ箇所がグラフィカル表示されます。

(公式ではTouch Debuggerをシーンに追加するとありますが、現バージョンではTouch Visualizerに置き換わっているようです)

タップ操作を取り扱う

ここからが本題となります。ここではシーン上のCubeをタップすると何かしらのアクションが発生するようにしましょう。そのためにCubeにTouchScript/Gesture/TapGestureをアタッチします。

これによってCubeがタップジェスチャを検出できるようになります。この状態でCubeをタップすると、Cube内のTapGestureクラスが送信元ととしてTappedイベントが発行されます。
あとはTappedイベントのハンドラを用意し、TapGestureクラス内のTappedイベントにハンドラを登録すれば目的達成です。次のスクリプトをCubeにアタッチします。

using System;
using TouchScript.Gestures;
using UnityEngine;

public class TapFire : MonoBehaviour {

    // オブジェクトが有効化されたときにイベントハンドラを登録する
    private void OnEnable()
    {
        GetComponent<TapGesture>().Tapped += tappedHandler;
    }

    // オブジェクトが無効化されたときにイベントハンドラを削除する
    private void OnDisable()
    {
        GetComponent<TapGesture>().Tapped -= tappedHandler;
    }

    // タップイベントのイベントハンドラ
    private void tappedHandler(object sender, EventArgs e)
    {
        if (transform.localScale.x > 0.05f)
        {
            Color color = new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value);
            for (int i = 0; i < 8; i++)
            {
                var obj = Instantiate(gameObject) as GameObject;
                var cube = obj.transform;
                cube.parent = transform.parent;
                cube.name = "Cube";
                cube.localScale = 0.5f * transform.localScale;
                cube.position = transform.TransformPoint(directions[i] / 4);
                cube.GetComponent<Rigidbody>().AddForce(power * UnityEngine.Random.insideUnitSphere, ForceMode.VelocityChange);
                cube.GetComponent<Renderer>().material.color = color;
            }
            Destroy(gameObject);
        }
    }

    public float power = 10.0f;

    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のときと同じように、用意したPlaneにTouchScript/Gesture/TapGestureをアタッチします。イベントハンドラはTouchScriptに用意されているサンプルTouchScript/Examples/Taps/Scripts/Spawnを使用します。イベントハンドラの登録は先ほど同様ですので、ここではイベントハンドラの中身だけを見てみます。

private void tappedHandler(object sender, EventArgs e)
{
    // TapGesture型にキャスト
    var gesture = sender as TapGesture;
    // 位置情報等が含まれているTouchHit構造体の変数を用意し、TapGestureのメソッドからデータを取得する
    TouchHit hit;
    gesture.GetTargetHitResult(out hit);

    var cube = Instantiate(CubePrefab) as Transform;
    cube.parent = Container;
    cube.name = "Cube";
    cube.localScale = Vector3.one*Scale*cube.localScale.x;
    // タップした場所にあらたにCubeを生成する
    cube.position = hit.Point + hit.Normal*.5f;
}

タップした位置情報等は、EventArgsではなく、イベントの送信元であるTapGestureが保持しています。TapGestureではタップジェスチャを検出した際にタップしたスクリーン座標からRayを飛ばし、ターゲットのオブジェクト(ここではPlane)のどこにHitしたかをチェックしています。そのデータはGetTargetHitResultメソッドに渡したTouchHit構造体から取得することができます。

まとめと今後

各種ジェスチャ操作を簡単に取り扱えるアセット、TouchScriptの導入方法と基本的な使い方をまとめました。今回はジェスチャの検出対象がオブジェクトである場合の例でしたが、TouchScriptでは画面全体を検出対象とすることもできます。また、デフォルトで用意されているジェスチャも複数ありますので、今後はもう少し実践的な使い方を整理したいと思います。