はじめに

前回Mirage Solo の6DoF 対応コンテンツをマッハで Build するを読んでくださった皆さんお久しぶりです!

前回記事では、 CRS を Mirage Solo で動かすという Unity 界隈での新 VR デバイス Hello World よろしくな事をしましたが今回はもう少し突っ込んでいじってみようと思います。

使用する Unity バージョンは2018.1.4です。

今回使用するコンテンツ

clipboard.png

2016年に Release されたなごみの耳かきを Mirage Solo に移植していきます。

これを移植すると決めた理由?可愛いからです。

なお、プロジェクトデータを Unity5.3系から Unity2018.1へ大ジャンプをすることになり色々苦労しましたが本筋とは違うので割愛します(虚空を見つめる目)。

PlayerSettings の設定

まずは大きいところから設定していきましょう。前回の記事と同じように下記の設定をすれば OK です。

BuildTarget を Android に設定しましょう。 PlayerSettings で変更する内容は画像の赤枠部分です。

  • 色空間を Linear から Gamma に
  • MinimumAP を Android7.0に(Daydream は7〜なので)
  • VR サポートに Daydream を追加

clipboard.png

GVRSDK の設定

前回は Unity の Virtual Reality Supported 機能だけで Build しましたが、今回はコントローラーを使いたいので GVR の SDK を追加します。

下記リポジトリにある GoogleVRForUnity_1.130.1.unitypackage(2018/6 最新)を使用します https://github.com/googlevr/gvr-unity-sdk/releases

UnityPackage をインポートすると色々と追加されますが、使うものは Prefabs フォルダでまとまっています。

clipboard.png

  • GvrControllerMain
  • GvrEventSystem
  • GvrEditorEmulator

この3つを Hierarchy の適当な場所に起きます。今回は Scene の Root においてますがどこでもいいはずです。

個人的にはマルチシーン構成にして、こういう Singleton 的な使い方をする諸々は別 Scene に突っ込みたいところです。

  • GvrInstantPreviewMain

この Prebfab は Build せずにリモートでアプリを走らせることができます。(ARkitRemote に似てますね)

お好みで追加してください。使い方の詳細はこの記事がオススメです。

Daydream 開発入門 その2(Instant Preview)

最後に「 GvrControllerPointer 」をカメラと同じ階層に設置します。これを別の場所に置くとコントローラやレーザーポインタが正しく描画されなくなってしまう原因になるのでちゃんとカメラと同じ階層に配置してください。

clipboard.png

UI の調整

スマホ版のなごみの耳かきは、ゲーム本編が始まるまでの操作は画面タッチです。

(本編が始まる直前に HMD にスマホを刺します)

つまり本編以外の GUI は Render Mode が Screen Space Overlay になります。

で、今回です。

起動直後から HMD を被っていなければなりません。

真面目に本編以外を VR 空間用に対応するには時間が足りません。

今回は Render Mode を World Space にしてお茶を濁しましょう。

また Canvas の GameObject にGvr Pointer Graphic Raycasterの Component を追加しましょう。

Daydream コントローラーで uGUI の EventSystem に対応されて Button を押せるようになります。

clipboard.png

メインシーンの調整

メインシーンの調整をしていきましょう。といってもスマホ版は iPhone5S で動くように調整されています。

計算が重くて動かないとかは全くないです。

また、 GVR の前身の CardboardSDK で開発されたのでシステムの大改修が必要になるわけでもありません。

ということで、手間は掛かりませんでした。

部屋モデル改修

Mirage Solo は6DoF の上に管理者設定で制限を外せば無限に歩くこともできます。

(設定の外し方はコチラMirage Solo の移動範囲を無限にする方法)

「よし、なごみちゃんと居る部屋を思う存分歩くぞ!」ってなるのは必然ですが大きな問題があります。

外の景色、書割なんですよね……

clipboard.png

これでは6DoF 移動するとばれる……

外の景色作り……やるかーやるしかないかー

clipboard.png

UnityAssetStore でモデルを買って置くだけで簡単に景色が作れるから Unity は神です。

元の景色に池ないですが、縁側でなごみちゃんと池見たいなと思ったので作りました。

この和室、縁側ないんですけどね!!

clipboard.png

なごみちゃんのモデル微調整

なごみちゃんはユニティちゃん Shader v2で設定し直しました。セルフシャドウを切ってあるのでそんなに大きさ差はありません。

(実は VivePro 版も作ったのですが、その時はテッセレーションで輪郭が綺麗になったりするように調整しました。)

clipboard.png

あとは個人的な趣味で髪の毛が眼にかかった時は描画順を眼が手前になるようにしました。

clipboard.png

負荷調整

ちょうど作っているときに[Graphy] – Ultimate Stats Monitor & Debuggerが無償化されたので使ってみました。

PC はもちろん、スマホ上でもグラフィカルに FPS 表示が見えるようになったのでとても便利です。

clipboard.png

外景色にオブジェクト起きすぎて Set Pass Call がえげつないことになっていたのでMesh Bakerを使って簡略化します。

下記画像のオレンジ色で選択されたものを1Mesh にしました。

clipboard.png

木々は Unity の Tree で作ってあり風のアニメーションがあるので Mesh 結合はしませんでした。

MirageSolo のリセット仕様と格闘

Mirage Solo の仕様として、 HMD を脱ぐとポジトラの位置が0,0,0に戻るというものがあります。これをされてしまうと、「ここの景色見てもらえます?」って外して人に渡すと初期位置に戻っている、ということになり非常に面倒くさいです。

なのでコレを無理やり維持できるように直していきます。

まず、カメラの親にカメラの位置と回転を保存する Offset 用の親オブジェクトを作ります。

clipboard.png

Mirage Solo は HMD を外したときにスマホでいうスリープ状態に入るので「 OnApplicationPause 」でスリープ検知します。

スリープを検知したらその時のカメラのワールド座標とローカル回転を CameraOffset に放り込みます。


[SerializeField] private Transform _cameraOffseTransform;
[SerializeField] private Transform _cameraTransform;
private float _defaultOffsetRotation;
private Vector3 _defaultOffsetVector3;

private void Start()
{
    _defaultOffsetRotation = _cameraOffseTransform.localEulerAngles.y;
    _defaultOffsetVector3 = _cameraOffseTransform.position;
}

void OnApplicationPause (bool pauseStatus)
{
    if (pauseStatus)
    {   
        //カメラの位置保存
        _cameraOffseTransform.position = _cameraTransform.position;
        float roteY = _cameraTransform.localEulerAngles.y;
        _cameraOffseTransform.localEulerAngles += new Vector3(0f,roteY,0f);
    } 
}

こうすることで HMD を外した時にも位置と回転(Y 回転のみ)を引き継げるようになりました。

Mirage Solo の極端に狭い移動範囲等を考えると設計思想に反してる気がしますが今回は Release するわけでもないのでこんな無理やりでいいでしょう。

この保存機能をつけると次は保存したデータをリセットする機能が欲しくなるでしょう。(欲しくなるって言われた)

Mirage Solo は Daydream コントローラーのホームボタンを長押しするとトラッキングがリセットする機能があるのでこれを叩いたときに自動で行われるようにしましょう。

if (GvrControllerInput.HomeButtonState)でホームボタンの入力がとれるので Button が押されたら Camera の Offset 値が初期化されるようにします。

void Update () {

    if (GvrControllerInput.HomeButtonState)
    {
        resetCenter();
    }
}

void resetCenter()
{
    _cameraOffseTransform.position = _defaultOffsetVector3;
    _cameraOffseTransform.localEulerAngles = new Vector3(0f,_defaultOffsetRotation,0f);
}

さいごに

元のアプリが Android 用 VR アプリだったので、比較的ラクに移植できました。

Daydream のコントローラがコードを書かなくても uGUI の EventSystem に対応されるのが楽でいいですね!!

作ったアプリを堪能してつくづく思いました。ワイヤレス HMD で自由に歩けるのはホント楽しいです!!

エピローグ

上司:これ Mirage Solo で動いたってことは Oculus Go でもいけるよね?

私:行けるとおもいますけど……

上司: Oculus Go 版もよろしくネ!

ハコスコ用スマホ VR アプリを Oculus Go に移植してみる へ続く!