目次
はじめに
Unityクライアントエンジニアの大川です。
OculusQuest2が発売されて1年経ちましたね!
以下、私が1年前に書いたOculusQuest関連の記事になります。
OculusQuest2(その1) VRで物を掴む投げる離す
1年ぶりにOculusQuest2関連シリーズを投稿していきたいと思います。
今回はただ投稿するだけではなく、AppLabにアプリをリリースするまでを投稿していく予定です。
アプリを作る過程で必要な技術的な内容や、詰まったところ、技術以外の内容も書いていきたいと思います。
今回の内容
映画館で3D映画を見るような体験をVR空間で実現したいと思います。
私の頭の中にあるゲームの企画でこのような表現が必要なので考えてみました。
現実世界でも仮想現実世界でも、3D空間の中で3Dに見える2Dスクリーンを実現することになります。
仕組みは単純でスクリーンに2種類の映像が映っていてそれぞれ左目と右目にしか見えないようにして立体的に見えるようにしています。
現実世界ではメガネでフィルターをかけて特定の光を遮断することで実現していますが、仮想現実世界では片目だけに描画する設定にすることで実現できます。
実際にUnityでの実現方法を書いていきます。
ほとんどコーディングする必要がなく、簡単に実現できました。
デモ動画
実機では3Dで浮かび上がっているように見えていますが、動画は2Dなのであまり伝わらないかもしれません。
サンプルプロジェクト
今回作成したプロジェクトはこちらです。
https://github.com/k-okawa/QuestSandBox/tree/master/Assets/Sample/3DScreen
セットアップ
UnityVersion:2020.3.21f1
今回メインとなる内容ではないので詳細は省きます。
公式ドキュメントはこちらです。
https://developer.oculus.com/documentation/unity/unity-gs-overview/
しかし、1年ぶりに環境構築して一つ詰まったところがあったので記述したいと思います。
正しく環境構築をすれば、UnityEditorで実行をしたときにOculusQuest2本体に映像が映しだされるのですが、映し出されないという問題がありました。
原因は単純で、ProjectSettings/XR Plug-in ManagementのDesktopタブのOculusにチェックをつけ忘れていました。。。
実装手順
1.OVRCameraRigを追加する
Oculus Integrationに含まれているOVRCameraRigを配置します。
シーン上にMainCameraがすでにおかれている場合は削除してください。
2.OVRCameraRigComponentのUsePerEyeCamerasにチェックを入れる
こちらにチェックを入れることで左右のカメラの設定をそれぞれ変更することが可能になります。
3.レイヤーを追加
ProjectSettings/Tags and LayersでLeftEye,RightEyeを作成します。
4.カメラの描画レイヤ指定
OVRCameraRigのLeftEyeAnchorとRightEyeAnchorのCameraのCullingMaskをそれぞれ以下のように設定します。
このようにすることで、これから作成するLeftCanvasは左目にだけ描画され、RightCanvasは右目だけに描画されるようになります。
5.RenderTextureを2つ作成する
カメラの出力先をテクスチャにするためにRenderTextureを左右用に2つ作成します
サイズはそれぞれFullHDで設定しておきます。
6.Canvasを2つ作成
先にLeftCanvasを作成した後、複製してRightCanvasを作成します
Imageの設定
黒縁を表示するために追加してあります。
LeftCanvasの設定
Layerを設定する際こちらが表示されましたら、Yes, change childrenを選択して子オブジェクトもレイヤーの設定が適用されるようにしてください。
RawImage
RightCanvas設定
LeftCanvasを複製し、LayerをRightEye、RawImage Textureを3DScreenTextureRightに設定すればOKです。
7.別世界を作成
1.適当な世界を作る
OVRCameraRigから離れたところに別世界を適当に作ります。
(LayerでOVRCameraRigでは映らないようにするか、カメラの描画距離の設定で映らないように設定したほうがよいです)
2.2つのカメラを設定
カメラが重要で、左目だけに描画するカメラ・右目だけに描画するカメラを作成します
※カメラのAudioListenerはRemoveしておいてください
Camera親オブジェクトを作成し、左と右をすこし離すようにして配置します。
1で作成したRenderTextureをそれぞれのTargetTextureに指定します。
3.カメラの位置を同期するスクリプト
Cameraの親オブジェクト(Cameras)にOVRCameraRigのカメラの動きを同期するスクリプトをアタッチします。
こちらは頭を上下左右に動かしたときにある視点では見えないキューブの側面などを見ることを可能にすることで、3Dをより感じやすくするためです。
今回のスクリプトは単純です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using UnityEngine; public class ThreeDimensionScreenCameraSync : MonoBehaviour { [SerializeField] private Transform _centerEyeAnchor; private Vector3 _originPos; void Start() { _originPos = transform.position; } void Update() { transform.position = _originPos + _centerEyeAnchor.localPosition; } } |
centerEyeAnchorにOVRCameraRigのCenterEyeAnchorをセットする
今回はカメラが静止していることを前提にしているので、カメラを動かす場合は別途スクリプトを考える必要はありますが、今回は単純な方法をとっています。
最後に
手順は少し長いかもしれませんが、簡単なスクリプトと設定だけで3Dスクリーンを実現することができました。
次回はCanvasから別世界に対してのRayCast判定をする方法がないか調査したいと思います。