Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【Oculus Quest開発メモ】ALVR実行時にAvatarGrabの手が出ない問題 Hand編【Unity】

 

今回はOculus Questの開発ネタをやっていきます。

Oculus QuestをALVRで起動した時にAvatarGrabシーンで手が出ない問題を解決します。
OculusQuestのバージョンアップでALVR関係なく手がでないことが起こりますが、そちらも解決します。

f:id:Raspberly:20190808234352g:plain

 

 

 

 

開発環境

Windows 10

Unity 2018.4.5f

Oculus Integration ver1.39

Oculus Quest

ALVR

 

 

ALVRとは

こちらで少し触れています。

raspberly.hateblo.jp

 

簡単に言うと、PC向けVRの映像をOculusQuestなどスタンドアロンHMDに転送するソフトウェアです。
これにより、毎回ビルドしなければならないQuestの動作テストをEditor上ですぐに動作させることができます。

 

 

 

 

Oculus Questのバージョンアップデート

7月下旬にOculusQuestがアップデートされました。
この時、同時に少し不具合が起きています。これらの不具合はALVR関係なく起こります。

まずはこちらの手段をお試しください

 

・コントローラーが片方したトラッキングされない! 

AvatarGrabシーンでクラッシュする!

といった問題は以下のQiitaを参考にしてみてください・

qiita.com

kimono-oyaji.com

otasyumi.site

 

 

追記、Oculus Integration 1.40の場合

Oculus Integrationのバージョンによって微妙に解決方法が異なりますが1.40の場合、マニフェストの編集で解決します。

  • OVRCameraRig にアタッチされている OVR Manager の Target Devices の “Gear Vr Or Go” を “Quest” に変更する
  • 以下のメニュー操作で Asset/Plugins/Android/AndroidManifest.xml を作る
    • Oculus > Tools > Remove AndroidManifest.xml
    • Oculus > Tools > Create store-compatible AndroidManifest.xml

なお、Build And Run を実行したときに

DeploymentOperationFailedException: No activity in the manifest with action MAIN and category LAUNCHER. Try launching the application manually on the device.
UnityException: Could not find any valid targets to launch on for Android

というエラーが出る場合は、生成された AndroidManifest.xml

<category android:name="android.intent.category.INFO"/>

のところに

<category android:name="android.intent.category.LAUNCHER"/>

を書き足すととりあえず上手くいくようです。

詳しくはこちらをどうぞ。

framesynthesis.jp

 

 

 

前提条件

OculusIntegrationを使用しており、ALVRで動作確認をしようとしたところ手が表示されない状態であること

Androidビルドなら表示されていること。

 

 

 

 

 

主要コンポーネント

Hand

ハンドというのはかなり大雑把な名前ですが、手のアニメーションや描画、当たり判定の切り替えを担当するコンポーネントです。 

 

 

 

 

 

サンプルシーンの確認

Assets/SampleFramework/Usageに様々なサンプルシーンがあります。
学習や挙動の確認にとても有益です。見てみましょう。

 

実は正常に表示されるシーンがあります、それはCustomHandsシーンDistanceGrabシーンです。

f:id:Raspberly:20190809101910p:plain
この2つのシーンではGrabberにOVR GrabberDistanceGrabberコンポーネントがアタッチされていますが、
Handコンポーネントもアタッチされていることを確認しましょう。

f:id:Raspberly:20190808175854p:plain

 

このHandコンポーネントはAvatarGrabシーンではアタッチされていません。

f:id:Raspberly:20190808175957p:plain

当然、プレハブ化されているAvatarGrabberやLocalAvatarWithGrabも同様です。

 

 

 

Hand

f:id:Raspberly:20190808180055p:plain

インスペクターパラメーター

Controller

手のタイプ、右手なら「R Touch」、左手なら「L Touch」にするとよい

Animator

子オブジェクトにある手のモデルのAnimator

Default Grab Pose

 

 

 

 

 

Handの修正

手が非表示になる時、Hand.csを編集するだけで解決することがあります。

Hand.csのOnInputFocusLostメソッドを以下のようにします。
renderers[i].enabled部分をコメントアウトします。

 

 

 

 

Handの手動追加

上記でHand.csを修正しても手が表示されない時はHandを手動で追加します。

コンポーネントのアタッチ

まず、両手のAvatarGrabberにHandコンポーネントをアタッチします。

f:id:Raspberly:20190808204949p:plain

 

そしたら、HandのControllerを修正します。右手ならR Touch、左手ならL Touchにします。
この値はOVR GrabberのControllerと同じ値にするといいでしょう。

f:id:Raspberly:20190808210034p:plain

 

手のモデル

Assets/Oculus/SampleFramework/CostomHands/Modelsの中にある、
「l_hand_skeletal_lowres」と「r_hand_skeletal_lowres」を
Handコンポーネントががアタッチされているオブジェクトの子オブジェクトにします。

f:id:Raspberly:20190808210631p:plain

f:id:Raspberly:20190808211046p:plain

 

AnimatorControllerがnullなので、右手左手に応じたAnimatorをアタッチします。

f:id:Raspberly:20190808233153p:plain

f:id:Raspberly:20190808233114p:plain

 

パラメータの設定

先ほど子オブジェクトにした手のモデルを、HandをコンポーネントのAnimatorに設定します。

f:id:Raspberly:20190808232906p:plain

 

最後に、Default Grab PoseにAssets/Oculus/SampleFramework/CostomHands/Modelsの中にある、
HandPoseDefaultPfプレハブを設定します。

f:id:Raspberly:20190808233439p:plain

f:id:Raspberly:20190808233719p:plain

f:id:Raspberly:20190808233750p:plain

これでHandの設定は終了です。

 

うまくいけば、無事手が表示されていると思います。

f:id:Raspberly:20190808235841g:plain

うまくいかなかった場合は↓
 

 

 

 

 

 

シーン再生時にTime.timeScaleが0になる

スタンド攻撃を受けている

 

調べても同じ報告が出てこないので私の環境だけかもしれませんが、
シーン開始時にtimeScaleが自動的に0になる場合があります

そもそもシーン開始時に手が動いていない場合はこの可能性を疑いましょう。

f:id:Raspberly:20190809002151p:plain


この状態になると視点移動はできますが手が動かず、物理演算も止まります

Update()の中でDebug.Log(Time.timeScale);を呼び出すと、毎フレーム0が呼ばれます。

シーン開始時にtimeScaleが0になるようなら以下のスクリプトを適当なオブジェクトにアタッチしましょう。

 

 

 

 

 

 

【8月9日追記】時間が止まる問題への対策

この問題について解決策を教えていただきました。
どうやらシーン内で悪さをしているコンポーネントがいるようです。

 

シーン内にある、DynamicにPauseOnInputLossコンポーネントがアタッチされています。

f:id:Raspberly:20190809091245p:plain

このコンポーネントは、OVRManagerのInputFocusLostにイベントハンドラを登録しています。

InputFocusLostは入力が失われた時に呼ばれるイベント変数で、初回Update時に実行されているようです。

コンソールで"[OVRManager] InputFocusLost event"が出ている場合、この可能性が大!

 

解決方法としては、シンプルにPauseOnInputLossを無効化するといいでしょう。

f:id:Raspberly:20190809100124p:plain

 

この現象はOculusQuestがアップデートされる前から稀にあったのでとても助かりました。

@shienaさんありがとうございます。

 

 

 

 

 

まとめ

・手が表示されない場合、Hand.csを編集してみる

・それでもだめなら、Handを直接追加してみる

・それでもだめなら時間が止まっていないか確かめる

 

 

 

  他間違っている箇所、わかりにくい点がありましたらコメントにお願いします。