Skip to content

Questジェスチャー機能

参考サイト:

【Unity】Questのハンドトラッキングで特定の手の形を認識して処理を走らせる【Meta XR Interaction SDK】 - Qiita

Oculus Interation SDKを使って、ノーコードで簡単にオリジナルのハンドジェスチャを実装する

パッケージマネージャーよりMeta XR Alli-in-One SDK をインポート

Meta XR All-in-One SDK

画面右下にoculasマークが出る

基本は参考サイト通り

Building Blocksより

  • Camera Rig
  • Hand Traking
  • Synthetic Hands

を追加。

image.png

project上で create→Oculus→Interaction→SDK→Pose Detection→shape

で定義したい形状を作成していく

ハンドポーズについて

Meta Developers

※親指のFlexionは偽陽性になることがある

image.png

など詳しい説明があった

image.pngimage.png

Meta XR Alli-in-One SDKがあるとなぜかエラーを吐き続けるため、Quest3サンプルアプリ動作確認のときと同じものを使用することに

本来はなにかしらトリガーを発生させてイベントを起こすということをしたかったが、ジェスチャーをもとにスクリプトをよぶものの例が見つからなかったため、参考にした、

【Unity】Questのハンドトラッキングで特定の手の形を認識して処理を走らせる【Meta XR Interaction SDK】 - Qiita

が行っていたように一度テキストをかえ、ジェスチャーの変更をそのテキストの変更をもってスクリプトでうけとるという方式に

image.png

スクリプト:

csharp
using System.Collections;
using UnityEngine;
using TMPro;

public class JankenManager : MonoBehaviour
{
    [SerializeField] private TextMeshPro tmp1;
    [SerializeField] private TextMeshPro tmp2;
    [SerializeField] private TextMeshPro tmp3;

    private enum Hand
    {
        None,
        Rock,
        Paper,
        Scissors
    }

    private Hand playerHand = Hand.None;
    private Hand opponentHand = Hand.None;
    private Hand[] handArray = { Hand.Rock, Hand.Paper, Hand.Scissors };

    private void Start()
    {
        StartCoroutine(JankenRoutine());
    }

    private IEnumerator JankenRoutine()
    {
        while (true)
        {
            tmp1.text = "Rock-paper-scissors...";
            tmp2.text = "";
            playerHand = Hand.None;

            opponentHand = handArray[Random.Range(0, handArray.Length)];

            // TMP3の内容を監視してplayerHandを決定
            yield return new WaitUntil(() => tmp3.text != ""); // 何か表示されるまで待つ

            switch (tmp3.text)
            {
                case "Rock":
                    playerHand = Hand.Rock;
                    break;
                case "Paper":
                    playerHand = Hand.Paper;
                    break;
                case "Scissors":
                    playerHand = Hand.Scissors;
                    break;
                default:
                    // 想定外の値が入っていた場合の処理(必要に応じて)
                    Debug.LogWarning("Unexpected value in tmp3: " + tmp3.text);
                    break;
            }

            string result = JudgeResult(playerHand, opponentHand);

            tmp1.text = $"The opponent's hand was {opponentHand}.";
            tmp2.text = result;

            yield return new WaitForSeconds(10f);
        }
    }

    private string JudgeResult(Hand player, Hand opponent)
    {
        if (player == opponent)
        {
            return "draw";
        }

        if ((player == Hand.Rock && opponent == Hand.Scissors) ||
            (player == Hand.Paper && opponent == Hand.Rock) ||
            (player == Hand.Scissors && opponent == Hand.Paper))
        {
            return "You Win!";
        }
        else
        {
            return "You Lose!";
        }
    }
}

GestureDemo.mp4

110.jpg

グーとパーの認識は容易だったがチョキの認識の制度が悪かった。ジェスチャーの設定を変えることで精度向上(アバウトな認識をさせる)ができるかも。複雑なジェスチャーを作成するには注意が必要


Author: 水上 | Source: 水上\Questジェスチャー機能 efc87b175783434cb4ce4ffc0ca416dd.md