見出し画像

手の動きでモンスターボール投げ! 5

↑ これの続きです。

前回まで技術検証を行ってきました。今回は ToF AR (主にハンドトラッキング機能) を追加し、手の動きでボールを投げるトリガーをかけるように改造していきます。

動作の様子

今回は Xperia 1 III を使用しています。

ネタのためにモンスターボール人形を使って撮影しましたが無い方が手認識されやすいです(笑)

GitHub リポジトリ

Unity 側は以下です。Scene は ThrowUnity5 です。

Android Studio 側は以下です。ADB.exe から指定して実行するプログラムは TouchServer4.java になります。


解説

ToF AR のダウンロード・インストール・初期設定などは、下記の記事を参考にしてください。

Android 向けに必要な追加設定は下記の記事を参考にしてください。

必要な Prefab をシーンに配置する

「iPhone で Air 太鼓の達人を作る 4」に記載のある Prefab に加え、 以下の 2 つの Prefab を Hierarchy へ配置します。Assets の検索機能で探すのがおすすめです。

・TofArColorManager
 Color 映像(通常のカメラ映像)を使うために必要。

・ColorViewRawImage
 Color 映像(通常のカメラ映像)を表示する Raw Image
 UI 用なので Canvas 内に配置する。

その他設定すること

Hand Model を手前に表示させ、その裏に ColorViewRawImage を表示させたいので、Canvas の Render Mode を「Screen Space - Overlay」から「Screen Space - Camera」へ変更しておきます。

ジェスチャ推定を利用するため、配置済の TofArHandManager の Inspector にある「Auto Start Gesture Estimation」にチェックをいれます。

ジェスチャ推定でボールを投げる

ToF AR には、一定の手の動きを検出する機能があります。検出できるジェスチャ一覧は以下のページで確認できます。

今回は「ボールを投げる動き」なので、
「Hand Throw」と「Finger Throw」のどちらかを検出したら
という処理にしたいと思います。

Hand Throw
Finger Throw
public class ThrowDetector : MonoBehaviour
{
    public TouchClient client;
    public Text gestureText;

    private GestureIndex detectedGesture = GestureIndex.None;
    private float last = 0;

    void Start()
    {
        // コールバック関数の登録
        TofArHandManager.OnGestureEstimated += GestureEstimated;
    }

    /// <summary>
    /// ジェスチャ検出されたときに呼び出される。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="result"></param>
    private void GestureEstimated(object sender, GestureResultProperty result)
    {
        // ジェスチャの種類
        GestureIndex gi = result.gestureIndex;
        detectedGesture = gi;
    }

    void Update()
    {
        float current = Time.realtimeSinceStartup;

        if (detectedGesture != GestureIndex.None)
        {
            bool throwBall = 
                (detectedGesture == GestureIndex.HandThrow
                    || detectedGesture == GestureIndex.FingerThrow);

            detectedGesture = GestureIndex.None;
            last = current;
            gestureText.text = "" + detectedGesture;

            if (throwBall)
            {
                client.ThrowBall();
            }
        }

        // ジェスチャ検出後 1 秒間表示
        float alpha = Mathf.Max(0, 1.0f - (current - last));
        gestureText.color = new Color(0, 0, 0, alpha);
    }
}

プログラムはこんな感じです。
・Start 関数でコールバック関数の登録
・Update 内でジェスチャ種類に応じた処理
 (メッセージ送信処理は TouchClient.cs の ThrowBall 関数で行われる)
・ジェスチャ発生後1秒間だけテキストの文字を濃くして表示

分割表示やタッチ操作発生などと組み合わせることで、色々なことができそうです。今回はネタ成分が高めですが、実用的な使い方を考えたいところです。

(続くかも)

この記事が気に入ったらサポートをしてみませんか?