この記事でのバージョン
Unity 2017.4.2f2
はじめに
以前Standard Assetsというディレクトリを使って、コンパイル時間を短くする方法をご紹介しました。
今回は似たような事をAssembly Definition Filesを使ってやてみよう!という記事です。
Assembly Definition Filesとは
そもそもAssembly Definition Filesとはなんぞや?という話からですが、
マニュアルを見てみると以下のように(Google翻訳)書いてました。
Unityは、スクリプトが管理されたアセンブリにどのようにコンパイルされるかを自動的に定義します。通常、プロジェクトにスクリプトを追加すると、反復スクリプトの変更に対するUnity Editorのコンパイル時間が長くなります。
アセンブリ定義ファイルを使用して、フォルダ内のスクリプトに基づいて独自のマネージアセンブリを定義します。これを行うには、スクリプトで変更を加えるときに必要なアセンブリのみが再構築されるように、適切に定義された依存関係を持つ複数のアセンブリにProjectスクリプトを分離します。これによりコンパイル時間が短縮されます。Unityプロジェクト内では、各マネージアセンブリを単一のライブラリと考えることができます。
ざっくりまとめると、
好きなようにコンパイルする範囲を設定でき、それがコンパイル時間短縮に繋がるという事です。
例えばプログラムのファイルA, Bがあった時、通常なら
Aだけを編集した場合でもAとB両方をコンパイルしてしまいますが、
Assembly Definition Filesを使えば
Aを変更した時はAだけコンパイル(Bをコンパイルしない分早くなる)
なんて事が出来るわけです。
使い方
使い方は簡単、Createの項目からAssembley Definitionを作成し、
コンパイルを分けたいディレクトリに入れるだけ。
ただし、Auto Referencedが有効になっていると毎回コンパイル対象になるのでオフにしておきましょう。
これだけでコンパイルが別に行われるようになり、コンパイル時間を短縮出来るようになります。
また、スクリプトがどのアセンブリに属しているかはAssembly Informationで確認出来ます。
なお、デフォルトではAssembly-CSharp.dllと表示されます。
このように簡単に使えますが、一つ注意が必要なのが
アセンブリを分けたもの同士のスクリプトはデフォルトでは参照出来ません。
例えば以下のようにAとBでアセンブリを分けた場合、
BからAを(AからBでも)参照しようとするとエラーが出ます。
using UnityEngine; public class A : MonoBehaviour { public static int A_VALUE = 10; }
using UnityEngine; public class B : MonoBehaviour { void Start () { //BからAは参照出来ないのでエラー int a = A.A_VALUE; } }
こんな時はBのアセンブリにはAのアセンブリが必要だよ!という事を設定します。
設定の仕方はBのDefinition FilesのReferencesに、AのDefinition Filesを登録するだけ。
ただし、BにはAが必要だし、AにもBが必要みたいな依存しあってる設定には出来ません。
なお、アセンブリを分けてない(Assembly-CSharp.dllに属している)スクリプトから
アセンブリを分けたスクリプトを参照する事は問題ありません。
以下の例だと、CからAやBを参照する事は可能です。(逆は駄目)
おわりに
依存関係を設定し始めると、かなりごちゃごちゃして余計な手間が増えそうなので、
依存関係を設定せずに済むようなものだけを別コンパイルにするのが、楽な使い方になりそうです。
なお、プラットフォーム毎にコードを分けたりも出来るようです。
------------追記------------
コンパイル時間の短縮を図るタイミングを決めるための
アセンブリごとのコンパイル時間を計測したり、閾値を越えたら警告を出したりするやつを作りました!
------------追記おわり------------