ハンドトラッキングにおいての「掴む」ということ

ためすこと

ハンドトラッキングでオブジェクトを「掴む」ということ

環境

Unity 2019.3
Android SDK
Oculus Ver 12以上

方法

そも、ハンドトラッキングに「掴む」という動作は用意されていない
これは公式にも明記されてる

developer.oculus.com

今回はピンチ操作を元に「掴む」を実装してみる。
オブジェクトを掴む判定ているとき、

  • 案1:手とオブジェクトの相対値を固定する
  • 案2:オブジェクトを手の子要素として扱ってしまう(手の一部とみなす

今回は2でいく

まずオブジェクト

今回はCubeをつかう

f:id:gamaspecial:20200608193202p:plain

掴むにおいて物理的な接触が発生するので、RigidBodyを追加する

docs.unity3d.com

これを追加することで、「Collision」を使用できる。

docs.unity3d.com

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeTouch : MonoBehaviour {

    //Migite
    private GameObject rightHandAnchor;
    public MyHand hand;

    //flags
    public bool isPinch;
    public bool isCatch;

    public string collisionName;

    void Start() {
        hand = FindObjectOfType<MyHand>();
        rightHandAnchor = GameObject.Find("RightHandAnchor");
    }

    void Update() {
        isPinch = hand.isPinch;

        if (isPinch == false) {
            isCatch = false;
            gameObject.GetComponent<Rigidbody>().useGravity = true;
            gameObject.GetComponent<BoxCollider>().isTrigger = false;

            gameObject.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
            gameObject.GetComponent<Rigidbody>().isKinematic = false;
            gameObject.GetComponent<Rigidbody>().transform.parent = null;
        } else if (isCatch == true) {            
            gameObject.GetComponent<Rigidbody>().useGravity = false;
            gameObject.GetComponent<BoxCollider>().isTrigger = true;

            gameObject.GetComponent<Rigidbody>().transform.SetParent(rightHandAnchor.gameObject.transform);
        }
    }

    void OnCollisionStay(Collision other) {
        if (other.gameObject.name == "Hand_Index3_CapsuleRigidBody" ||
            other.gameObject.name == "Hand_Index2_CapsuleRigidBody" ||
            other.gameObject.name == "Hand_Thumb3_CapsuleRigidBody" ||
            other.gameObject.name == "Hand_Thumb2_CapsuleRigidBody") {

            collisionName = other.gameObject.name;

            if (isPinch == true) {
                isCatch = true;
            } else {
                isCatch = false;
            }

            gameObject.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
            gameObject.GetComponent<Rigidbody>().isKinematic = true;
        }
    }
}

f:id:gamaspecial:20200608194158p:plain

改善が必要!!!