はじめに
イケメンテックラボで 「王子様のささやき朗読VR」の メインエンジニアを務めている、茨田と申します。
今回はUnityでどのようなことをすればVR化ができるのか、また、開発に便利なGoogleVR SDKの導入方法を説明していきたいと思います。
開発環境
「王子様のささやき朗読VR」では、開発当初、Daydream Viewというゴーグルに、スマートフォン(Galaxy s8)を差し込む形式で開発をしていましたが、
開発途中でスタンドアロンのVRゴーグル、OculusGoが出たので、そちらでも並行して開発を開始しました。
Unityは当時は2017.4.xを使っていました。
今回の記事では2018.2.12を使用します。
また、筆者はMacで開発をしているため、Windowsの場合は少し差異があるかもしれませんが、ご容赦ください。
アンドロイドの開発環境やSDK、NDK、JDKなどのUnityへのパス通しなどは終わって居る想定で記事を書いています。まだ終わっていない場合は、下記の外部記事などを参考に、導入を済ませてください。
UnityからAndroid実機ビルド手順(2017.08版)
https://qiita.com/relzx/items/7f8e7817c9edd11c5023
UnityでVR開発をするには?
Unityではver 2017辺りからVRは標準搭載になっているため、設定周りを色々変更することでVR化ができるようになっています。
また、開発する上で、GoogleVR SDK(以降GVRと呼ぶ)を導入することで、端末のジャイロセンサーを使用し、上下左右どちらに端末を傾けたか?など、Unityのエディタ上で動きを真似することができるようになり、開発効率が上がります。そのほかにも、視線ポインターでの当たり判定やDaydream Controllerのポインタの当たり判定など、VR上で便利に使える機能などがあります。

これらをどのようにすれば使えるようになるのか、説明させていただきます。
Unity上の設定
今回は新しいUnityプロジェクトを作って説明していきます。
まず最初に、File > Build Settings を選択してBuild Settingsウインドウを開きます。

次に、Build Settingsウインドウの左側のプラットフォーム一覧から[Android]を選択して左下の[Switch Platform]ボタンを押します。

[Switch Platform]ボタンの横にある[Player Settings]ボタンを押すとInspectorに[Player Settings]の画面が開かれます。Build Settingsウィンドウは設定が終わったので消しましょう。

[Player Settings]の一番下にある[XR Settings]を選択してから[Virtual Reality Supported]のチェックボックスにチェックを入れてONにします。

[Virtual Reality SDKs]の[+]ボタンを押して[Daydream]と[Cardboard]を追加することで、対応したスマートフォンにVRをビルドできるようになります。
※[Oculus]を選択することでOculusGoなどにもビルドすることもできます

追加した[Daydream]と[Cardboard]の[▶︎]を押すと設定画面が出てきます。
両方の[Depth Format]を[24-bit depth | 8bit stencil]に設定しておくとAndroid上でも透過の処理が使えるようになります。
※「王子様のささやき朗読VR」では、髪の毛を透過して、目や眉毛を前面に押し出すアニメ的な表現に利用しています

[Daydream]の[Positional head Tracking] を[Disabled]にします。
※今回使用しているDaydreamViewには位置のトラッキング用の機能がないため、OFFにしています。6DOFに対応しているヘッドセットではONにしましょう
以上でUnity側のセッティングは終わりです。
次は開発効率をあげてくれるGVRの導入に進んでいきましょう。
GVRの使い方
以下のページからGoogleVRForUnity_x.xxx.x.unitypackageをDLします。
https://github.com/googlevr/gvr-unity-sdk/releases
今回は2019/2/5時点で最新のGoogleVRForUnity_1.190.1.unitypackageをDLします。
※「王子様のささやき朗読VR」ではver1.120.0を使っていました

Unityを起動して Asset > ImportPackage > CustomPackageを押し、先ほどDLしたGoogleVRForUnity_x.xxx.x.unitypackageを選択し[Open]ボタンを押します。

[Open]ボタン押して処理が終わったら[Import Unity Package]ウインドウが開きます。
右下にある[Import]ボタンを押すことで、現在チェックがついているものをインポートできます。
※必要なければDemosフォルダなどのチェックを外してもいいです

ProjectのAssets > GoogleVR > Prefabs にあるGvrEditorEmulatorを[Hierarchy]にドラックアンドドロップ(D&D)します。

これで、Unity実行時にキーボードのoptionを押しながらマウス移動でゴーグルで上下左右を見たときの様な視線操作ができる様になりました。
試しに適当なオブジェクトを置いて実行して見ましょう。
[Hierarchy]を右クリックして[3D Object]の中から[Cube]を選択します。

[Hierarchy]内にCubeが生成されるので選択します。
[Inspector]にCubeのデータが表示されます。
[Transform]の[Position]の[Z]を10に設定しましょう。

Cubeと同じ様に今度はSphereを生成し、Sphereの[Z]は-10に設定しましょう。
これでカメラの前後にオブジェクトを置くことができました。
Unityの[Play]ボタン(▷のボタン)を押して実行して見ましょう。

optionを押しながらマウス移動で視点を動かして、カメラの真後ろにあるSphereが見られれば成功です。

当たり判定について
Daydreamでは主に2種類の入力方法があります。
Daydreamについてくるコントローラーによる入力と、GVRの機能である視線による入力です。
今回は「王子様のささやき朗読VR」で使用した視線による入力を説明します。
今回視線を採用した最も大きな理由が、VRゴーグルをつけると手元がほぼ見えない状態になり、その状態でコントローラを操作するのが初心者には難しいと判断したためです。コントローラも慣れれば便利ですが、今回はVR熟練者向けのアプリではなかったため、少しでもわかりやすい、視点での操作になりました。
当たり判定を行いたい場合、シーン上にAssets/GoogleVR/Prefabs/EventSystemに配置されているGvrEventSystem.prefabをHierarchyに設置します。
これにより、コントローラや視線による当たり判定が行われる様になります。
※シーン上に置けば設置位置などは関係ありません

次に、視線と当たり判定を行いたい物体にBox Colliderなどの衝突する範囲と、ポインターが物体と接触したり、離れたりなどするときに、スクリプトが呼べるEvent Triggerを設定します。
Event TriggerはPointerEnterが当たり判定に入ったときでPointerExitが当たり判定を出たときなど、様々なタイミングで任意の処理をスクリプトから仕込むことができます。

このとき設定する物体は、UIオブジェクトだと反応がありません。3Dオブジェクトか2Dオブジェクトを対象に当たり判定をつける様にしましょう。
例えば、2DオブジェクトのSpriteや3DオブジェクトのCubeは当たり判定が動きます。UIオブジェクトのPlanelやImageでは当たり判定が動きません。

次にカメラ周りの設定をします。
Assets/GoogleVR/Prefabs/Cardboardにある、GvrReticlePointer.prefabをMainCameraの子として設置します。
MainCameraの子にすることで、頭の動きと同じ様にPointerも動く様になります。
MainCameraにPhysics RaycasterをつけることでColliderなどの衝突する範囲と判定ができる様になります。

GvrReticlePointerを設置すると、画面の中央にポインタの点が出ており、当たり判定を設定した物体に当たると点が広がって円になる様になります。

今回はオブジェクトもレティクルも白で確認しづらいため、レティクルの色を変えていきます。
GvrReticlePointerをInspectorで確認すると一番下にRariclePointerというマテリアルがあります。これを[▶]ボタンで展開すると、Colorの項目が出てきます。Colorの白い部分をクリックして好きな色に変えることができます。今回は赤色にしてみます。

上記の設定でレティクルの色を変えることができました。

以上が当たり判定の説明になります。
Event Triggerと組み合わせることにより、一定時間そこを見つめるとキャラクタが登場したり、オブジェクトと視線が当たったらオブジェクトを消すなど、様々なことが実現できるようになります。
「王子様のささやき朗読VR」では空間上にビッキー王子が急に現れるので、ビッキー王子の出現場所とは逆の暖炉を見つめることをトリガーにして出現させることにより、体験者には空間上に急に現れる不自然さを見せないように工夫しています。
VRでやるときのTIPS
GvrEditorEmulatorにについて
GvrEditorEmulatorを入れると[Play]時に[MainCamera]のTransformのPositionやRotationが初期化されます。
これを回避して、[MainCamera]の初期位置や回転角度を動かしたい場合、[Hierarchy]を右クリックして、[Create Empty]で空のゲームオブジェクトを作り、空のゲームオブジェクトの子として[MainCamera]を設定することで回避できます。
[MainCamera]は位置や回転など初期化されますが、親の空のゲームオブジェクトのTransformを操作することで、任意の位置や回転などをした状態で、VRを開始することができます。

uGUIのRenderModeについて
uGUIのCanvasの[Render Mode]設定は[Screen Space – Overlay]ではなく、[World Space]を使う事をお勧めします。
[Screen Space – Overlay]はUIが画面を追従するため、頭を動かしているのにUIがついてきてしまいます。また、人間の眼は近過ぎる物には焦点を合わせることができないので、この設定はVRに適していません。
[World Space]は空間配置型なので、空間の何処かにポスターを貼る様なイメージでUIを設置することができます。適切な距離で配置することでユーザーが焦点を合わせやすくなります。

RenderingのColor Spaceについて
一部スマートフォンのGPUがLinerColorSpaceと相性が悪いため、実機にビルドすると全体的に画面が暗くなってしまう場合があります。なので、実機にビルドして画面が暗くなってしまった場合は、GammaColorSpaceにすることで回避できることがあります。
「王子様のささやき朗読VR」開発中には、galaxy s8のGPUであるsnapdragon845で、不具合が起きていて、画面がかなり暗くなってしまっていたため、Gammaを採用しました。

エディターの画面サイズの設定について
エディタでVRをエミュレートしていると実際の機器と画面の幅が違い、実機で見るのと印象がかなり違う場合があります。
その対応として、実機の横向きにしたときの画面解像度を調べて、横向きだけ半分にした数値を設定することで、VRで2眼を描画するときと同じくらいのサイズにすることができます。これにより、エミュレートしている場合でも実機との見た目とそれほど差異の無いものにできます。
Galaxy s8の場合、横向きにしたときの画面解像度は2960 * 1440だったため、1480 * 1440に設定していました。

おわりに
今回は、UnityのVRの設定方法と、GVRの導入方法についてと、いくつかのTipsを説明させていただきました。
次回以降も、「王子様のささやき朗読VR」で使った技術やTipsなどを紹介させていただきますので、よろしくお願いいたします。