デコシノニッキ

ホロレンジャーの戦いの記録

HoloLensのIL2CPPでの開発

Unity2018より,Scripting Backendに.NETを指定すると「将来的に.NETはサポートされなくなり、IL2CPPが標準になります。」といった内容の警告が表示されるようになります。実際,いくつかのUnityの標準APIが.NET環境だとビルドできず,IL2CPPのみのサポートになったりしています。2018.3現時点ではサポート対応が続いているも,2019でどうなるかはまだわかりません。

f:id:haikage1755:20180922212240p:plain:w350
Unity2018で.NETを選択した際の警告

この将来的な変更に対する議論がこちらでなされていました。色々と参考になったのでここのリンクベースで説明していきます。
UWP without .NET? How do you get fast?

この変更に対する公式の意見があるので英語大丈夫という方はこちらを読んでください。
f:id:haikage1755:20180922213322p:plain:w350


.NETが使えなくなることによって起こる問題

問題点について先に触れます。
まずは,Unityからのビルド後にソースコードの変更が加えられなくなった点。IL2CPPでは,UWPのプロジェクトを吐き出しはしますが,その中身はマネージドアセンブリC++に変換したものです。(IL2CPPの仕組み) このおかげでJITコンパイルに比べて一般的にパフォーマンスがでるといった恩恵を受けられる訳ですが,マシンによって変換されたコードはとても人の手に負えるものではありません(できる人はできるんだろうけど)。また,プラットフォーム依存の処理の部分の書き分けも問題になります。WINDOWS_UWPなどで囲まれたディレクティブ内ではインテリセンスが効かないため,タイプミスといったエラーが頻発します。NETではUWPのC#プロジェクトとして出力できるため,Unityからビルド後にプラットフォーム依存の部分を別で開いたVSから書くといったやり方ができました。最終的にはIL2CPPを使いたいけど,変更の容易性や時間といった問題から,.NETで作業してからIL2CPPでビルドし直すという人もいるでしょう。

f:id:haikage1755:20180922212058p:plain:w350
defineディレクティブを使った処理の書き分け

IL2CPPでは先のリンクの方が質問で投げているように,.NETの数十倍近いコンパイル時間がかかります。これは,.NETアセンブリから使われていない部分をstripping(=除去)して,C++に変換するプロセスがあるため当然その分遅くなります。細かいコード修正で都度Unityからビルドするのは効率は悪いですし,やっている方も辛いでしょう(実際つらい)
2017.4の空プロジェクトの場合だと,あまり大きな違いがないようには見えますがプロジェクトの規模が大きくなってくるほどこの差は大きく開いていきます。

2017.4の空プロジェクトをビルドした結果(※環境に個人差はあります)

.NET IL2CPP
1回目 49秒 54秒
2回目 46秒 29秒

IntelliSense を有効にする

実はIL2CPPにスイッチングした状態でVSを立ち上げると,通常のプロジェクトに加えて.Playerというネイティブコードを記述できるプロジェクトが自動作成されます。Editor用のプロジェクトと、.Playerはスクリプトのみに関し同じ構造をとっています。それぞれのスクリプトを切り替えることで、ネイティブコード、それ以外などをインテリセンスが有効な状態で記述できます。

f:id:haikage1755:20181103054409j:plain:w350

Windows.Storageなどのネイティブコードを記述できる
f:id:haikage1755:20181103054856j:plain:w350

Editorに切り替えるとerrorになる
f:id:haikage1755:20181103055030j:plain:w350

Windows Player: IL2CPP build files - Unity マニュアル


ビルド時間の短縮

ビルド時間の短縮については,公式のマニュアルにも案内が出ています。

docs.unity3d.com

インクリメントビルドの使用

インクリメントビルドを行う場合、C++ コンパイラーは、最後にコンパイルしてから変更が加えられたファイルのみを再度コンパイルします。 インクリメントビルドを行うには、(ターゲットディレクトリを削除せずに) 以前のビルドロケーションと同じ場所にプロジェクトをビルドします。

 先ほどの計測で,突っ込んでいなかった部分です。2回目のビルド時間が大幅に短縮していた理由がこれです。ただ個人的な感想で言えば,プロジェクト規模が大きくなってくるとあまり効果を感じにくくはなりますね。

プロジェクトとビルドフォルダーをマルウェア対策のソフトウェアスキャンから除外

プロジェクトをビルドする前に、マルウェア対策のソフトウェアを無効にしてビルド時間を向上させることができます。(Unity テクノロジーズの検証では、新しくインストールした Windows 10 で Windows Defender を無効にした後、50 – 66% ビルド時間が減少しました。)

フルで切るわけにはいかないので,今回はプロジェクトフォルダがある場所をDefenderの対象から外します。

Windows Defender-> ウィルスと驚異の防止 -> ウィルスと驚異の防止の設定の項の「設定の管理」-> 除外の項の「除外の追加または削除」から除外を追加します。
この状態での計測結果です。確かに50%近くまでビルド時間が減りました。

IL2CPP IL2CPP(Defenderなし)
1回目 54秒 34秒
2回目 29秒 26秒

プロジェクトとビルドフォルダーを Solid State Drive (SSD) に格納

Solid State Drive (SSD) は以前からあるハードディスクドライブ (HDD) に比べ、より速く読み込み、書き込みを行えます。IL コードを C++ に変換しそれをコンパイルすることは、大量の読み込み、書き込み操作を伴います。ストレージデバイスのスピードが速いと、この処理もより早くなります。

これに関しては特に突っ込みません。そうだよね。うん。

Script Only Build

リンク先で紹介されていた方法です。ビルドの対象をスクリプトに絞り込みます。
BuildSettingsでDevelopment モードを有効にした時のみに選択可能になります。

f:id:haikage1755:20180922232415p:plain:w350

こちらに関しては,一度ビルドしたTarget先を選択する必要になります。

f:id:haikage1755:20180922232838p:plain:w350
新規でScriptOnlyBuildでビルドした際のエラー

計測結果です。これくらいの規模だと特に時間は変わりませんでした。

IL2CPP IL2CPP(ScriptOnlyBuild)
1回目 54秒 -秒
2回目 29秒 28秒

まとめ

IL2CPPでのワークフローについての調査でした。2018.3から使えるいくつかの新機能もIL2CPPに制限されていたり,既に終わりの始まりは見えています。
出る出る詐欺なのかどうかはわかりませんが,HoloLens2も恐らくUWPでの開発がメインになるでしょう。ですので,.NETでの開発がメインの方も2018.3の大きな変更を機にIL2CPPでの開発環境に慣れてみてはどうでしょう。

[デコシノニッキ]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」