見出し画像

VR日記その27 -Oculus Questでハンドトラッキングを実装する

久しぶりの技術系記事です。

こちらと

こちらを参考にさせていただきました。

環境設定

使用アセットはこちらです。Oculus公式のSDK。まだMetaではなくOculusでした。

Oculus Linkを使ってゲームを再生する場合

・Build SettingsをWindowsに
・XR Plugin ManagementのOculusにチェックを入れる(XR Plugin Managementがない場合はインストールする)

※BuildSettingsがAndroidの場合だと再生ボタンを押してもうまくOculusで再生できませんでした。

実機にビルドする場合

※今回はビルドしてないのでもしかしたら間違いがあるかもです。参考程度に。

・Build SettingsをAndroidに
・Player SettingsのColor SpaceをLinear
・Minimum Api Levelを25以上に
・Script BackendをIL2CPPに
・Target ArchitectureのARM64にだけチェックを入れる
・XR Plugin ManagementのOculusにチェックを入れる(XR Plugin Managementがない場合はインストールする)

ハンドトラッキングをするまで

めっちゃ簡単でした。コードいらずのお手軽3ステップです。

①Oculus Project Configの「HandTrackingSupport」をHandsOnlyにする

Controllers and Handsでも良さそうですが誤動作しそうなのでHandsOnlyにしました。

②LeftHandAnchorとRightHandAnchorに「OVRHandPrefab」を追加する

③RightHandAnchorのOVRHandPrefab内の設定をHand Rightにする

赤線の部分です。

終了。早い。

実際にやってみた

ちゃんと表示されるし、滑らかに動きますね。手が重なると奥の手が消えるようです。影絵で遊ぶのは難しいかも?
ちなみに、コントローラーが動いている状態だと手が検知されないので、確かめるときはどこか安定したところに置いておきましょう。膝の上に置いておいたらずっと表示されなかった。
この辺に関しては公式にも記載があります。

https://developer.oculus.com/documentation/unity/unity-handtracking/?locale=ja_JP#understanding-hand-tracking-limitations

値を取得する

折角なので少し遊んでみた。

チェンソーマンの「コン」がしたい

アニメ化もするので、元ネタが分からない人はこれを機に読んでみてください。

出来たのがこちら。
原作のような迫力を出すのは難しいので、今回は簡単に「狐の形を作ると狐が出る」という部分を作りました。

実装内容

こちらを参考にしました。

指同士がくっついているかどうかはGetFingerIsPinching(指の値)というメソッドを使えば簡単に判断することができるようです。引数としての指の値は5本分用意されているので、理論上は色々なパターンが検知できます。
ただし、先ほどの開発メモによると、3本以上は精度が怪しいとのこと。

今回は狐の形なので、親指、中指、薬指の3本の接触を検知する形になります。動画にもあったとおり精度はあまり気にならず、いい感じに検知してくれました。
スクリプトはこちら。

using UnityEngine;

public class handtracking : MonoBehaviour
{
    [SerializeField] OVRHand ovrHand;
    [SerializeField] GameObject fox;

    [SerializeField] GameObject foxPosition;
    bool pinching;

    void Update()
    {
        if (ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Thumb) &&
            ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Middle) &&
            ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Ring))
        {
            if (pinching)
            {
                return;
            }

            Debug.Log("コン!");
            con();
        }
        else
        {
            pinching = false;
        }
    }

    private void con()
    {
        pinching = true;
        Instantiate(fox, foxPosition.transform.position, foxPosition.transform.rotation);
    }
}

if文の中で指が3つ重なった時を判断しています。

if (ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Thumb) &&
    ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Middle) &&
    ovrHand.GetFingerIsPinching(OVRHand.HandFinger.Ring))
{
}

bool pinchingはupdate関数の中で指がタッチされて続けていても、狐が一匹しか出ないようにするために追加しています。
最後に、con()メソッドの中で狐を召喚します。召喚位置の基準とするために、cubeを追加しています。
中々うまく位置が合わせられず試行錯誤した結果、下記のような位置と向きになりました。分かりやすさ優先でMeshは見えるようにしています。

全体像

ちなみに、今回は片手だけでいいかなと思ったので冒頭の [SerializeField] OVRHand ovrHand;には右手のみ入れています。

召喚する狐はアセットストアでなるべく可愛いのを見繕ってきました。

走る動作や攻撃どうさは組み込まれているので、召喚した瞬間に走る(3アニメーション分走る)→攻撃→消える(=非アクティブになる)をAnimatorで組み込んでいます。消えるアニメーションは自作です。

walkって書いてあるけどアニメーション名はFox_Runです。
アニメーションの繰り返しはもう少しうまいやり方があると思う

終わりに

他にもハンドトラッキングでは指同士の接触だけでなく、各関節の位置を取ることができるので、頑張ればいろいろなことが出来そうです。
今回はそこまで気力が続かなかったけどいつかやってみたい。

こちらや

こちらが参考になりそう。

VRの開発久しぶりにやったけど楽しかったです。ARもVRもどっちも楽しい。

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