Unity2021.2.4f1のURPで、OpenXRのみでVRアプリ開発をする


概要

こんにちは!
VRChatを中心にXR関係の活動をしているサックーと申します。
これはUnity2021.2.4f1のURPで、OpenXRのみでマルチプラットフォームVRアプリ開発をした記録になります。
Iwaken Lab.「好きな技術・コト」 Advent Calendar 2021の11日目の記事です。
動機としては、買ったけど眠らせてたHDRP・URP限定のインタラクティブな水アセットをVRで使いたいというものです。
ついでに色々整ってきたOpenXRだけを使って、SteamVR PluginやOculus Integration抜きでマルチデバイスなアプリにしてみようと欲張ってみました。

使用する技術

  • Unity2021.2.4f1
  • OpenXR Version 1.2.8
  • XR Interaction Toolkit Version 2.0.0-pre.5

流れ

  • OpenXRを使って基本のVRアプリセッティング
  • アセットを使って中身を作る
    • アバターのセットアップ
    • おまけ

とりあえずVRアプリにする

OpenXRでVRアプリを作る基本については、こりんさんのこちらのページ
Unity VR開発メモ(XR Interaction Toolkit + OpenXR Plugin)
を参照してください。情報が早くて網羅的な神ページです。

「Oculus Questで実行できるようにする」というところまで設定を進めてください。
一部写真を追加して補足します。

プロジェクト作成の補足

Unity2021.2から?URPのコアテンプレートが追加されました。
サンプルシーンはないので余計なデータなしで簡単にURPプロジェクトを開始できます。
と思ってコアで作ったらAndroidビルドで件の水シェーダーがうまく動かなかったので、まだサンプルのテンプレートの方がいいかもしれません。

XR Interaction Toolkitのインストールについて補足

Package Manager右上の歯車からAdvanced Project Settingsをクリックして、Enable Pre-release Packagesをオンにするところ。

Package Manager左上の+ボタンからAdd package from git URL…で「com.unity.xr.interaction.toolkit」を追加するところ

ここまででおそらくとりあえずHMDをつないで実行したら6DoFで動いてくれるとは思います。
一点注意として実際にビルドするときはScene in Buildにビルドするシーンを追加し忘れないようにしましょう!!!
当たり前のことなんですがVRChatのワールド開発ばかりやってたせいですっかり忘れてました(2時間くらい溶かした…)

コントローラーで動けるようにする

最後にコントローラーで空間を動けるようにしましょう。
適当なオブジェクトにLocomotion Systemと移動と回転のコンポーネントを追加すればよいです。

移動は連続とテレポート、回転は連続とスナップの二種類ずつあります。
僕はどちらも連続(Continuous)を選びました。
スナップ回転はコンポーネントを変えるだけですが、テレポート移動は移動範囲などの設定が必要になります。

どちらのコントローラーを使うかのチェックをUse Referenceのところにいれ、適切なInput Action Referenceを選択します。
回転のInput Action Referenceを選ぶときにRotate ではなくRotation(おそらくコントローラー自体の回転)を選んでしまうと動かないので気を付けてください(1敗)
個人的にはMove Speedは2がちょうどよかったです。

ちなみに見た目上邪魔なのでXR Interactor Line Visualはオフにしました。

中身を作ってみる

ではここから実際に中身を作っていきます。
やりたいことは水と戯れることですが、せっかくなのでアバターを入れて動かしたいと思います。
使用するアセットは以下の通りです。

使用アセット

アバターは導入が簡単だろうということでVRMを入れましたが、あまり意味なかったかもしれません。
揺れ物がこれだけでセッティングできるのは便利ですね。
水アセットのサンプルシーンをベースに作っていきます。

アバターモデルのセットアップ

まずはVRMのPrefabをシーンに出してみるとまっピンクでした。

マテリアルエラーですね。
VRMの標準シェーダーMToonは現在URPに対応していません。
そこで前述の水アセットの作者さんがURP対応のMToon互換シェーダーを公開していたので、それを使わさせてもらいます。
解凍してShaderGraphsMToonForURPVR-master\Assets\SimplestarGame\ShaderGraphsMToon以下をプロジェクトにD&Dして導入しました。
後は元のMToonのマテリアルを選択して、Shader Graph/MToonにシェーダーを変更します。

かわいい
シャーロちゃんはいいぞ

ちなみに標準で用意されているURP用のシェーダーの中だとUnlitがいい感じでした。

あと今回は使いませんでしたが、Standard等のBuilt-inシェーダーの変換には、公式のツールであるRender Pipeline Converterが使えます。

下記ページを参照してください。

3点トラッキングで動かせるようにする

今回は定番FinalIKのVRIKを用います。
まず前準備として、頭と手の位置が来るオブジェクトの下に子要素を追加しておきます。

次にXR Originの配下にアバターのモデルを入れます。

そしてモデルのルートにVRIKのコンポーネントを追加し、SolverのHeadとLeftHand、RightHnadを埋めます。

これでひとまずアバターとして動かせるようになりました。
しかし実際に実行してみると色々不都合があります。
手の角度や位置がおかしかったり、カメラにアバターの頭が映りこんだりしたりしていると思います。
手などのトラッキング位置の問題は先ほど追加した子要素の位置や角度を調整します。

後はVRIKのパラメーターを頑張って調整しましょう…僕もよく分かってないです。
カメラの問題は前述の位置調整や、カメラのClipping PlanesのNearを大きくすると改善すると思います。

それでも移動時に映りこんでしまったので、顔と髪の毛のメッシュのレイヤーを分けて、メインカメラではカリングしました。

ちょっと遊べるようにする

最後にアバターで水と戯れられるようにします。
とは言えこの仕組みはアセット特有のものなので割愛します。
ざっくり手の位置にコライダーとRigidbody入れてエフェクトなどの設定をしました。

せっかくなのでそれに加えて物を持って投げられるようにしました。
これも簡単で、持ちたい物にコライダーとXR Grab Interactableというコンポーネントを追加するだけです。

あとカメラとレンダーテクスチャで鏡っぽいものを作りました。

さらにせっかくのURPなのでポスプロも使ってます。
適当にBloomとか入れました。

完成

そうした完成したものがこちらになります。