どうも、蒼水です。
前回の記事の続きになります。
atelier-aomi.hatenablog.com
今回はハンドトラッキングでピンチ度合い、いわゆる指の閉じ具合を取ってみるところまでやってみたのでまとめていきます。
今回の目的
今回はハンドトラッキングをするうえでやはり操作していくうえで入力って必要ですよね。
Oculusホームで使えるハンドトラッキングでも指を閉じて操作すると思います。これを自分で開発するときにどうやるのか、という部分になります。
これをできるようにすることで指のジェスチャーで操作を可能にします。
OVRHandにある使える関数
GetFingerIsPinching(HandFinger finger)
この関数は指定した指が他の指を触れてるかどうかをBoolで返してくれます。
指にはそれぞれの指を指定できます。(Thumb/Index/Middle/Ring/Pinky)
基本的には親指(Thumb)を指定してやれば他の指と触れてるかどうかになるのでこれで良い気がしました。
GetFingerPinchStrength(HandFinger finger)
この関数は指定した指とのピンチ度合いをfloatで返してくれます。
こちらも同様に指の指定ができ、基本的にはThumbでいいかなと思います。
実際に数値を取って表示してみる
指定した指のピンチ度合いFloat0~1
— あおみゆい (@Yui_Aomi) 2019年12月29日
親指と他の指が接触してるかどうかBool pic.twitter.com/7VVkG53QUB
こちらは試しに取った値をテキストで表示してみたものです。
指の動きに合わせてそれぞれ数値が取れてるのが分かると思います。
これを使って条件分岐とかに使って処理を追加していけば何かしらできるのかなーと踏んでいました。
処理を追加してみる
なるほどね?(ちとガタついたりしてるのでいじらんといかんが基本的なことはできてる気がする。 pic.twitter.com/53ipkxK9S9
— あおみゆい (@Yui_Aomi) 2020年1月2日
これは上記の2つの関数を使って処理を追加して動かしてみたものです。
手を握ることでうちの子を手をつないでフリフリできるシステムを組んでみました。
うちの子はかわいいなぁ(迫真)
手を握るとはいえ、Thumbを指定しているので他の指をの接触が検出できれば手をつなぐことができるようにしてあります。
サンプルコード
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HandGrabber : MonoBehaviour { //手の指定 public GameObject LeftHand; public GameObject RightHand; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } private void OnTriggerStay(Collider other) { var lefthand = LeftHand.GetComponent<OVRHand>(); var righthand = RightHand.GetComponent<OVRHand>(); float LPitchingStrength = lefthand.GetFingerPinchStrength(OVRHand.HandFinger.Thumb); float RPitchingStrength = righthand.GetFingerPinchStrength(OVRHand.HandFinger.Thumb); //左手操作 if (LPitchingStrength >= 0.9) { this.gameObject.transform.parent = other.gameObject.transform; } else { this.gameObject.transform.parent = null; } //右手操作 if (RPitchingStrength >= 0.9) { this.gameObject.transform.parent = other.gameObject.transform; } else { this.gameObject.transform.parent = null; } } }
解説
まず前提としてこのコードではあらかじめキャラの手を動かすためのIKを使っています。
AnimatorのIK Passにチェックを入れ、それ用のスクリプトを用意していますがここでは割愛します。(別記事で書きたい)
コードとしては手がIK targetになるオブジェクトと接触しているときに閉じ具合が0.9以上の時にIK targetを手の子にすることで移動できるようにしています。
0.9以下のとき親子関係を解除してその場に固定できるようになっています。
LeftHand, RightHandはIK targeになるオブジェクトでOVR Hand Prefabを入れています。
今回はGetFingerPinchStrengthを使用していますがGetFingerPinchでも問題ない気はします。
実際最初そちらでやっていましたがほぼ同じ動きをしていました。
まとめ
基本的には「GetFingerPinchStrength()」「GetFingerPinch()」の二つを使っていくことになるのかな?と思います。
トラッキングの精度はかなり良いのですが手が重なったりするとやはり精度が落ちてしまったり、そもそも手が消えてしまうのでガタついてるのが現状ではあります。
もう少しいい感じにしたいところ....今後検証項目。
親子関係の作成とAnimator使ったIKの話を別記事で書こうかなと思います。