ハンドトラッキングを自分のコードで実現する解説は色々ありますが、ある方のブログがわかりやすかったので実装を試みたのですが、UnityやQuestの開発経験が少ないため色々と調べました。そのログです。断片的になりますが、元記事を読み込んでわからなかったときに参考にしてもらえればと思います。
以下が、この記事で動かそうとした元記事になります。
この記事はQuest2やUnityのプロジェクトの設定が終わった状態からはじまっていますので、まず、以下の記事をみてセットアップします。
とりあえず、上記の記事の「ビルド・実行する」までやればいいと思いますが、その下の方にも有用なことが書かれていますので、それもやります。ポイントを書きます。
「プロジェクトの基本設定について」の「その他」はやりました。
あと「ビルド設定」に書かれている以下を読んで、Mono&ARMv7に変更したら確かにビルド時間が2,3割?減ったように思います。条件によるのだと思いますが。プロトタイプ作りが目的なのでこれでいいと思います。
IL2CPP ビルドは遅いので、開発中や、ストアにリリースするつもりのない制作物では Mono でいいかもしれません。
あとはずーっと下にいって「ハンドトラッキングについて」の「ハンドトラッキングを使用するには」をやりました。Unityは2021.2.0f1をOculus Integrationはv33を使用していますが、最初にOculus Integrationをインポートしたときあとに「OpenXRを使うか?」みたいなダイアログが出て意味もわからずYesを押しました。結果、ハンドトラッキングはできているはずだけど手が描画されないという妙なことになりました。たぶん、以下の設定が悪かったのだと思います。
Oculus Integration 32.0のOpenXRバックエンドではハンドトラッキングがまだ完全にサポートされておらず手が描画されません。Oculus > Tools > OpenXR > Swithc to Legacy OVRPluginでレガシーのOVRPluginに切り替える必要があります。
設定はここまでで、あとは動作検証ですが、これも上記の記事の「ハンドトラッキングを使用するには」に書かれている方法で検証してみました。よく忘れるのですが、ビルド実行前に、Sceneをこのサンプルシーンに切り替えるのを忘れずに。
Oculus/VR/ScenesフォルダにあるHandTestシーンがハンドトラッキングの最小限のサンプルシーンなので、こちらを動かしてみるのが手っ取り早いです。
ここまで出来たらやっと元記事に戻ります。
サンプルを動かしたり、元に戻したり、という操作はUnityでは一般的すぎて解説がないと思いますが、Unityではプロジェクト内で複数のシーンを開発できます。この辺はUnityの基礎をやらないとなかなか感覚がわからないですね。
あとやったことは、最初の記事が参照している1個前の記事が以下なのですが、そこに書いてある情報を参考にしながら設定しました。
色々と書いているのですが、最低限必要なのは以下だと思います。
●HierarchyからMain Cameraを削除する。
●AssetsのOculus/VR/PrefabsからOVRCameraRigを選び、Hierarchyにドロップします(絵が上記の記事にあります)。
●同じく、AssetsのOculus/VR/PrefabsからOVRHandPrefabをLeftHandAnchorとRightHandAnchorの下に置く。
ここまで設定してハンドが表示されたらまずOKと思います。
そして、やっと最初にご紹介した元記事です。この記事では色々と実験をしながら進めているのですが、最終的にやりたいのは「ハンドトラッキング機能で物体をつまむ」なので、それを実現するための方法を再度書いてみます。元記事をまず読んで試してみてもしうまくいかなかったら読んでみてください。
まず、HierarchyのトップにSphereを作成します。元記事では指先につけて物体同士の干渉センサーとして使用するためのオブジェクトです。Positionはスクリプトで移動するため0,0,0でいいです。Scaleで大きさ調整ですが、XYZとも0.03にしました。以下のような感じです。
さらに、Sphereを干渉センサーとして使用するため、Sphere Colliderの is Trigger にチェックを入れます。
あと、元記事では指先をVR内でも確認しやすいように半透明にしていますよね?これもUnity開発に慣れていれば説明不要のことですが、僕はすっかり忘れていたのでググって調べました。
操作だけ書きますが、Assetsのトップで右クリックしてCreateを選びMaterialを選択します。するとAssetsの中にNew Materialができますので、InspectorのRendering ModeをTransparentに変更し、Albedoを押してAのグレーのカラーバーを中間くらいにします。Aはアルファ値で透明度を表します。設定したら、HierarchyのSphereをクリックし、MaterialsのElement 0に作成したNew Materialのアイコンをドロップすれば半透明にできます。
さらに、SphereのInspectorの最下段にあるAdd Componentボタンを押して、New Scriptを押し、新規にスクリプトを作成します。名前は何でもいいと思います。作成したスクリプトをダブクリしてエディタ内に元記事の「スクリプト」と書かれた50行くらいのコードをコピペします。元記事は最後の中括弧が抜けていますので加えましょう。
スクリプトを追加できたら、SphereのScriptのInspectorには以下のような入力欄が出来ているはずです。僕はスクリプトにgrabという名前をつけましたのでそのように表示されています。
Noneと書かれたところに、Hierarcyから、RightHandAnchorの下に追加したOVRHandPrefabを選び、MY Right HandとMY Right Skeltonにドロップします。同じく、Hierarcyから、Spheraを選び、Index Sphereにドロップします。結果は以下のようになります。私は左右のOVRHandを区別するため右手はOVRHandPrefabRとしています。
あとは、床と摘むCubeを配置します。
HierarchyのトップにCubeを2つ新規追加します。
サイズと位置は結構、設定が難しいので、私の例を示しておきます。
床
つまむCube
つまむCubeにはSphereと干渉するため(OnTriggerStayが実行されるようにするため)、Rigidbodyコンポーネントを追加する必要があります。やり方は簡単で、Cubeを選択し、Inspectorウィンドウ内のAdd Componentを押して、Physics⇒Rigidbodyと選択するだけです。設定は特にありません。
あと、せっかくなのでOVRCameraRigのポジションも載せておきます。動いてしまえばあとの調整は好きにすればいいと思いますが、最初に見える状態にするのは慣れが必要と思いますので。要は、床とOVRCamera RigとつまむCubeとの相対的な位置関係(あとサイズも)が重要なんですね。
はい、以上でとりあえず動きました。昨日と今日で4時間くらい使ったように思います。わかってしまえば(というか思い出せば)1時間もかからないことですが、UnityやOculusのことを思い出すのにどうしても時間が必要で。忘れては思い出して、の繰り返しです。
はい、とりあえず何かお役に立てればと思います。
でわ!