【UE4】クリスマスイブの夜・Daydream実機起動検証してみた

メリークリスマス！！
[Unreal Engine 4 (UE4) その2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ue4second)25日目の記事です。

#まず初めに(お詫び)

「The Phantom Knowledge Project for UE4」というタイトルで書こうとしたのですが……

申し訳ございません！
自分のスキル不足で25日に間に合いませんでした！

理由は以下の4つです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/f5993c71-7b14-1ebe-cc1d-f7b80eb03258.png)
上記、ハイウェイのマテリアルが多く、まだ完全にマテリアルをあてきれていません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/0bec6229-4361-0b0d-4498-df46d31bb7b2.png)
特に板ポリを使用したシーンのカメラワーク調整に時間かかっています。
調整をミスって妙な隙間が空いたり、そもそも遠景がおかしかったり等々

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/d3ef8411-2107-b9d3-1628-69113e09d3f4.png)
そこそこ収拾してきましたが、見た目同じモデル、ボーンとメッシュの構造が微妙に違うためインポート（通称：FBXガチャ）の手間がかかっています。

あと、初めて触るUnityのTimeLineから片手程度しか触ったことのないUE4のシーケンサーへの変換作業に時間がかかっています。

上記の通り、作業項目とそれにかかる時間が多く、[例のアドカレ](https://qiita.com/advent-calendar/2017/ue4vrgame-create)が一区切りついた翌日21日夜から見ていましたが、時間が足りませんでした。

本当に申し訳ないです、来月以降もひたすら作業を進めてマテリアルを除いて公開できると判断した段階で改めて書きます。

#代わりに……

ただ謝罪記事だけ書くのは色々と申し訳ないので、24日は24時間あるから24時間以内で終わる検証内容を探しました。

結論からいうと、検証内容は「UE4はGoogle DaydreamコンテンツをGGJのように短時間の開発ってできるの？」という点です。

なぜ上記の検証をしたかというと、21日に対応端末持っていないのに購入したDaydreamViewが届いてしまったからです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/7ab4858d-d0de-e265-f48c-419acaf57370.png)
※Google Storeより画像引用

このままだと勿体無いですし、来たなら本気でDaydreamやろうと23日に秋葉原のイオシスでリファレンス機であるPixel2を購入してきました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/fd3aae9b-3f1a-e978-a6eb-84e754f012d6.png)
※Google Storeより画像引用

こういう検証はリファレンス機が一番です。

そもそもDaydreamの実装、というかモバイルVRの開発を一回もやったことがないので、現バージョン(UE4.18.2)で24日9:00～25日朝7:00まで

・Daydreamの実機検証時、ドキュメント読まない人間がやりがちな地雷を思いつく限り踏む

をやっていました。おかげさまで日曜のクリスマスイブ、ほとんどの時間をマテリアルビルドで潰すことができました。

~~そもそも自分はかなり追い詰められないとドキュメント(API)読まないので検証としてはうってつけ~~

色々と地雷を踏んだ結果、ゲームジャム等の短時間でDaydreamコンテンツを実機検証する場合、最初どんな感じでプロジェクト設定したらいいのか見えたので書いていきます。

※なぜ23日にやらなかったのかというと、夜に以下のことが判明したからです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ぐっ、僕としたことが酒飲んでたせいで肝心なモノ買い忘れた<br>まさか付属ケーブルが両方type-cだと？<br><br>ウチのPCに接続できねーw</p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/944502357211131904?ref_src=twsrc%5Etfw">2017年12月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">マジウケるwww<br>今日は車運転出来ないから明日だな</p>&mdash; 荻野雄季 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/944502650510360576?ref_src=twsrc%5Etfw">2017年12月23日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
（ケーブル売ってる近所の家電量販店まで徒歩1時間半かかるところに住んでます）

#プロジェクト設定

結論から言います。ゲームジャムやUE4でのAndroid開発が初めての方は、何も考えず、ドキュメントに書いてある通りに設定してください。

[Android クイックスタート]
(https://docs.unrealengine.com/latest/JPN/Platforms/Android/GettingStarted/index.html)
[Google VR クイックスタート](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/QuickStart/index.html)
[Google VR と Daydream デバイス](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/Daydream/index.html)
[GoogleVR ベスト プラクティス](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/BestPractices/index.html)

なぜかと言いますと、後述しますが実機検証するときに莫大なビルド時間がかかる時があるからです。（特に初回が長い）
上記ドキュメントに書いてある通りに設定すれば、最小のビルド時間で実機検証ができます。

また、こりんさんが記事を書いていますのでこちらも参考にしてください。
[UE4＋Google Cardboard開発メモ（Daydream対応）](https://framesynthesis.jp/tech/unrealengine/googlevr/)

さて、上記ドキュメントを守らず色々と直感でやるとどうなるか。
それを書いていきたいと思います。

##検証環境

以下の環境で試しています。

・OS:Windows 10 Home（64bit）[Windows 10 Fall Creators Updat適応済]
・CPU:Core i7-6700（3.4GHz）
・GPU:NVIDIA GeForce GTX 980
・メモリ:16GB
・Unreal Engine 4.18.2
・Google Pixel2(Android8.1)

検証に使用したテンプレートはVRテンプレートとファーストパーソンテンプレートの二つです。

##事前準備
[1.Android 向けゲーム開発に必要なセットアップ](https://docs.unrealengine.com/latest/JPN/Platforms/Android/GettingStarted/1/index.html)に書いてある通りにセットアップを済ませましょう。

※ゲームジャムの場合、ここの部分を設定すると新規プロジェクトを作成しても一部の設定は共通で設定されます。開発時の余計な時間が減らせるので必ずやりましょう

### 1.Android SDKをダウンロード
Android SDKはCodeWorksforAndroid-1R6u1-windows.exeファイルを実行するとPCにインストールされます。
ドキュメントによるとUE4に最適化されてるとのことなので、Android Studioから落とせるSDKよりはこちらを使ったほうがよさそうです。

UE4のエンジンをデフォルトの場所にインストールしている場合、以下の場所に実行ファイルがあります。

C:\Program Files\Epic Games\UE_4.18\Engine\Extras\AndroidWorks\Win64\CodeWorksforAndroid-1R6u1-windows.exe

※UE4.18の場合

容量に余裕があるなら、以下の画像の通りFullに設定してNextにすれば確実です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/3b96143f-a498-71d8-0317-5b1704e07ee9.png)

余裕がない場合、カスタムを選択して、以下のファイルを追加してインストールしてください

Android N
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/33f32ee8-6f21-f8f4-a814-4248a5305c89.png)

Android NDK,Java SDK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/2eff66fc-099c-2d9b-1450-9d4e10b78912.png)

Apache Ant
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/0ba72508-526d-b9dd-a025-c6178990b808.png)

デフォルトのまま進めた場合、上記のインストールは以下の場所になります。
C:\NVPACK

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/7f3c617e-102b-1015-ce84-5fba3e4f78f6.png)

### 2.プロジェクト設定(共通)


Daydream対応における、全プロジェクト共通の設定を行います。
新たにプロジェクトを作成するか、既存のプロジェクトで設定するか、どちらでもかまいません。

#### Android SDK

プラットフォームのAndroid SDKを開きます。
続いて、インストールしたSDKのパスを以下の通り設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/29de6598-266f-539b-598a-270e4d9c0801.png)

SDKをデフォルトでインストールした場合、以下の通り設定してください

| プロパティ名       |  パス |
|:-----------------|:------------------|
|Location of Android SDK|C:\NVPACK\android-sdk-windows|
|Location of Android NDK|C:\NVPACK\android-ndk-r12b|
|Location of ANT|C:\NVPACK\apache-ant-1.8.2|
|Location of JAVA|C:\NVPACK\jdk1.8.0_77|
|SDK API Level|matchndk|
|NDK API Level|android-24|

※NDK API Levelをandroid-24にしていない場合、Daydreamだとサウンドのエラーが表示されて起動後即落ちます。実機検証時の再ビルドが完全に時間の無駄なので上記設定を必ず守りましょう。

#### Accept SDK License

UE4.18からライセンスに同意する必要があります。

プラットフォームのAndroidを開き、Accept SDK Licenseボタンを押して同意してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/9b4e13c1-1072-2d05-05ec-e3c20d0b9628.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/e231d142-4d3a-d7c3-9047-bc5b88f3cbcb.png)

もし、SDKインストールで必要なSDKをインストールしなかった場合、仮に必要なSDKをインストールしたとしてもライセンスに再同意しないと、実機検証の起動時にエラーが発生して時間を無駄に過ごすことになります。

ライセンス認証ファイルは以下のフォルダにあるので、licensesフォルダごと削除してください
C:\NVPACK\android-sdk-windows\licenses

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/a6d249ef-e180-de59-5f06-5c9ebf39a421.png)

### 3.実機側の設定

実機の開発者モードとDaydreamアプリの開発者モードを有効にしてください。
実機の開発者モードのやり方は[2.Android デバイスの設定](https://docs.unrealengine.com/latest/JPN/Platforms/Android/GettingStarted/2/index.html)、Daydreamアプリの開発者モードは[Google VR のデバッグ方法](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/Debugging/index.html)を見てください。

ドキュメントに書いてある通りなので、ここでは省略します。

---

これで事前準備が完了しました。
一度やってしまえば次からはこの作業省略できるので、必ず行いましょう。

##プラグイン

プラグインの設定です。ここから先は各プロジェクトごとの設定になります。

### 必須

Google VRプラグインを有効にする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/f042afba-f0d5-3694-8eaa-38337b21b7fc.png)

これを有効にしていないと、実機に送ったとしても起動するのはただのAndroidアプリです。
実機ビルド時間がそのまま無駄になる上、プラグインを変更したらエディタを再起動する必要があるのでプロジェクト作成時に真っ先に有効にしてください。

### 任意
Google VR Motion Controllerプラグインを有効
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/727685e1-4bdd-526b-9b7f-2d453e003a01.png)

Google SDKに含まれているデフォルトのMotion Controller機能を使いたい場合は上記プラグインを有効にします。
※Daydreamトップページで表示される↓コントローラーのことです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/ca09ea6a-f57f-af8d-81fc-8e5fbe0d3574.png)


プラグインを有効にしている場合、Motion Controllerクラスである程度の代替が可能です。
コントローラーを使う必要がないのであれば、必ずしも有効にする必要はありません。

##プロジェクト設定

Google Daydreamのプロジェクト設定は[Google VR クイックスタート](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/QuickStart/index.html)と[Google VR と Daydream デバイス](https://docs.unrealengine.com/latest/JPN/Platforms/GoogleVR/Daydream/index.html)を参考に設定します。

なお、ここの設定を間違えると実機検証で**「時間を膨大に浪費した上にアプリが起動しないので、また時間を莫大に消費してアプリをビルドする」**ことが起きるので注意してください。

※もう覚えてないですが、この設定を検証するために色々と弄繰り回した結果、総合計で約9時間ぐらい重いビルド処理（主にシェーダーコンパイル）だけに時間を潰しました
※自分のクリスマスイブの時間を大体潰してくれたので暇ならありがたいですが

プロジェクトはVRテンプレートで作成後、プロジェクト設定とプラグイン設定のみしかいじってません。
当然、PCスペックがよければ実機転送の時間は減るので、これから書く無駄な浪費時間は参考程度にしてください。

### Rendering

Renderingの項目設定です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/75187b95-7781-2d28-7f9b-23a2f54589e0.png)

DaydreamではMobile HDRのチェックを**必ず外してください**（必須）

チェックを入れたまま実機起動するとアプリ起動後に**即クラッシュして落ちます**。
チェックを変更する度に、実機転送時に**重くて時間のかかるシェーダーコンパイルが走る**ために注意です。

Mobile HDR切り替えの検証：**約１時間半浪費**
（内45分ぐらいが無駄なシェーダーコンパイル時間）

つづいてVRの設定です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/2c9512c7-5d27-1848-62aa-edc277f523d3.png)

・Instanced Stereo

Instanced Stereoは有効になっていてもDaydreamでは特に影響はありません。
( PC (DirectX) とPS4に対応している機能のため)

Instanced Stereoのチェックを変えるとエディタ再起動の上、エディタ上で長いシェーダーコンパイルが走るので動作が重くなります。
ゲームジャムであれば、Daydreamの実機検証上で影響は無い以上、ここの設定は変えないほうがいいかもしれません。

・Monoscopic Far Field
4.18からDaydreamにも対応したとのことでしたが、こちらをチェック入れると実機では起動時になぜかクラッシュして落ちます。
他にも何か影響があると思うのですが、調べ切れていません。

このチェックを変更するとエディタ再起動の上、エディタ上で長いシェーダーコンパイルが走るので動作が重くなります。
また、Daydreamをサポートしているため変更後に実機起動すると重いシェーダーコンパイルが走ります。

パフォーマンスの最適化に有効な手段ですが、クラッシュしている原因がわからない上に無駄なシェーダーコンパイル時間を消費するハメになるので、ゲームジャムでは有効にしなくても問題ないかと思います。

Monoscopic Far Field切り替えの検証：**約1時間浪費**
（内40分ぐらいが無駄なシェーダーコンパイル時間）

・Mobile Multi-View
~~すみません、こちらはMonoscopic Far Fieldに時間を取られて完全には調べられていません。~~
~~後日検証結果を書きます。~~

追記　12/25

Mobile Multi-View調査しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/150cc643-8cae-cc8d-085d-c0589e951fa1.png)

DaydreamはMobile Multi-View Directを有効にすれば対応されます。

※Mobile Multi-Viewを有効にする必要があります。

Mobile Multi-View Directを有効にすると、無効にしていた場合に比べて明らかに処理速度が改善されているとわかるほど滑らかに動きます。
切り替えるたびにシェーダーコンパイルが走ってしまいますが、明らかなパフォーマンス向上が見込めるため、初期に有効にしてしまうのがいいと思います。


##Android

Androidの設定です。

### APKPackaging

まずSDKのバージョンを24に設定してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/7591ca9b-fd61-2286-93c9-e7c9b62fd73c.png)
もし、24未満でVR Viewが起動した場合、それはDaydreamでは無くCardboardです。
CardboardならDaydreamのアプリ起動に必須なモーションコントローラーが表示されないため、すぐわかると思います。

時間の無駄なので両方24以上に設定しましょう。

続いてEnable Gradle instead of Antのチェックを切りましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/529fe403-9fcf-00d2-d959-92b13f331d56.png)
このチェックが入っていることにより、実機起動時にエラーが発生する場合があります。
実機起動なら切っても問題ありません。

続いてドキュメントに従って、Disable verify OBB on first start/update.とEnable FullScreen Immersive on KitKat and above devices.にチェックを入れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/a3848dfb-c377-8c14-22ce-c0dbeff21fe9.png)

### Advanced APKPackaging

Configure GoogleVR to support specific hardware configurationsをDaydream
に指定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/ae63b1b2-2569-3cde-b8c3-ea7d720bdeb3.png)

また、Configure GoogleVR for sustatined-performance modeにチェックを入れましょう。

### Build

ここが一番重要です。ここの設定次第で実機動作で重いシェーダーコンパイルの回数がかなり増えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/995f9076-907d-0e20-326d-acad44dd67b2.png)

ドキュメント通り、以下の設定にします。

・Support armv7 (aka armeabi-v7a): Disable
・Support arm64 (aka arm64-v8a): Enabled
・Support OpenGL ES2: Enabled

Daydreamはarm64-v8aのみの対応のため、armv7を有効にしているとエラーが起きます。
ただし、arm64を有効にすると初回クック時間が大幅に追加されるとドキュメントに書いてあるため、シェーダーコンパイルが少ない初期の内に一度、実機起動をしたほうがいいかもしれません。

・Support OpenGL ES2
・Support OpenGL ES3.1

上記はDaydreamに対応しています。どちらかが有効にする必要があります。
体感的にOpenGL ES2がシェーダーコンパイルにかかる時間は小さいです。

現在、Daydreamに対応している端末でおそらくOpenGL ES3.1に対応していない端末はないはず（嘘言ってたらごめんなさい）なので、Daydreamオンリー対応であれば、ES3.1に切り替えても問題ないかと思います。
ただシェーダーコンパイルに時間がかかるので、GameJamであればES2のままにしたほうがいいかもしれません。

・Support Vulkan

こちらは**必ずチェックをはずしてください**。
シェーダーコンパイルに時間がかかる上、起動後即クラッシュします。
時間の無駄です。通常のAndroidアプリであれば、実機がVulkan対応していれば問題なく表示されますが、Daydreamではやめましょう。

Build切り替えの検証：**約6時間半浪費**
（内5時間45分ぐらいが無駄なシェーダーコンパイル時間）

※実機起動の初回クック時にBuildの全項目にチェックを入れるとどうなるか

VRテンプレートだと、約4時間ぐらいのシェーダーコンパイルと時間がかかるarm64のクックが走った上、起動時に即クラッシュして落ちます。

時間を贅沢に使ったことを非常に実感できるで、どうしても暇をつぶしたい時におススメです。
（GameJamだと致命的なので、Vulkanかarmv7にチェックが入っていると知った段階で即止めましょう。）

※初代フルスペックのSurfaceBookに同じ事をやらせたら、CPUとメモリが常に100%近い状態になり少なくとも半日は完全固まった（熱もすごかった）ので、こんなアホなことをするのはある程度スペックのいいＰＣがおすすめです。

#モーションコントローラー　イベント

モーションコントローラーが対応しているイベントは英語版のドキュメントに掲載されています。

[Use the Google Daydream Touchpad Buttons](https://docs.unrealengine.com/latest/INT/Platforms/GoogleVR/HowTo/MCTPButtons/index.html)
[Set Up Motion Controller for Google Daydream VR](https://docs.unrealengine.com/latest/INT/Platforms/GoogleVR/HowTo/MotionController/index.html)
[Use the GoogleVR Touchpad](https://docs.unrealengine.com/latest/INT/Platforms/GoogleVR/HowTo/MCTouchPad/index.html)

簡単に書いたモーションコントローラーで拾えるイベントの早見表です。

![IMG_7009.JPG](https://qiita-image-store.s3.amazonaws.com/0/104377/bb6beb15-b1a7-6202-e13f-b573b59601fd.jpeg)

※MotionController(L)のイベントも有効です

1/7追記

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/49f3b5a8-4d97-68c1-e61f-06c8af849029.png)
タッチパネルの各4つのボタンは上記サムスティックイベントで一括に取得することが可能です。
タッチパネルの押し込みのみを判定したい場合はサムスティックイベントを拾うようにしましょう

#カメラ

こちらも英語ドキュメントに記載されています。

[Set Up Cameras for GoogleVR](https://docs.unrealengine.com/latest/INT/Platforms/GoogleVR/HowTo/CameraSetup/index.html)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/b22420a6-7f62-b723-7a50-6a050b1e4093.png)
※公式ドキュメントより画像引用

まず、Pawnを継承したBPクラスを作成し、画像の通りシーンコンポーネントの下にカメラを配置します。

続いてBeginPlayで以下のように実装します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/cc2b8333-ddd3-35da-12d2-160687a705af.png)
※公式ドキュメントより画像引用

![image.png](https://qiita-image-store.s3.amazonaws.com/0/104377/e4bb94fd-b87e-c316-4130-701e471e8b28.png)
※公式ドキュメントより画像引用

Set Tracking OriginをEye Levelにセットし、シーンの位置を0,0,180でセットします。
Zの値は各VRコンテンツで最適な値を入れてください。

一応公式ドキュメントでは

>この数値は、センチメートルでのユーザの実際の起立した高さに設定する必要があります。

と書かれています。

#最適化

簡単に最適化を紹介します。こちらもドキュメントに書かれています。

[GoogleVRのベストプラクティス](https://docs.unrealengine.com/latest/INT/Platforms/GoogleVR/BestPractices/index.html)

ライトは全部Static固定など、色々と役に立つことが記述されているので、まずはベストプラクティスに書かれていることを守りましょう。

# まとめ

長々と勢いだけで書きましたが、大事なことは

・Mobile HDRのチェックを**必ず外す**
・Support armv7 (aka armeabi-v7a)のチェックを**必ず外す**
・Support arm64 (aka arm64-v8a)のチェックを**必ず付ける**
・Support Vulkanのチェックを必ず外す
・実機起動の初回クックは**非常に時間がかかる**
・**ドキュメントしっかり読もう！！！！**

という点です。太字の部分はテンプレートによってはチェックが付いていたりするので、実機確認の前に一度チェックしたほうがいい項目です。

ここをしっかりと把握できれば、おそらくGameJamでもUE4にてDaydreamコンテンツを開発することが可能だと思います。

来年のGGJ2018ではDaydreamの神コンテンツが量産されていると期待しています！
以上、Unreal Engine 4 (UE4) その2 Advent Calendar 2017完結です！！