(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!


Assembly Definition Filesを使って、コンパイル時間を短縮する【Unity】【Assembly Definition Files】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2017.4.2f2


はじめに

以前Standard Assetsというディレクトリを使って、コンパイル時間を短くする方法をご紹介しました。



今回は似たような事をAssembly Definition Filesを使ってやてみよう!という記事です。


Assembly Definition Filesとは

そもそもAssembly Definition Filesとはなんぞや?という話からですが、

マニュアルを見てみると以下のように(Google翻訳)書いてました。

Unityは、スクリプトが管理されたアセンブリにどのようにコンパイルされるかを自動的に定義します。通常、プロジェクトにスクリプトを追加すると、反復スクリプトの変更に対するUnity Editorのコンパイル時間が長くなります。

アセンブリ定義ファイルを使用して、フォルダ内のスクリプトに基づいて独自のマネージアセンブリを定義します。これを行うには、スクリプトで変更を加えるときに必要なアセンブリのみが再構築されるように、適切に定義された依存関係を持つ複数のアセンブリにProjectスクリプトを分離します。これによりコンパイル時間が短縮されます。Unityプロジェクト内では、各マネージアセンブリを単一のライブラリと考えることができます。

f:id:kan_kikuchi:20180506112954p:plain
Assembly Definitions - Unity マニュアル


ざっくりまとめると、

好きなようにコンパイルする範囲を設定でき、それがコンパイル時間短縮に繋がるという事です。


例えばプログラムのファイルA, Bがあった時、通常なら

Aだけを編集した場合でもAとB両方をコンパイルしてしまいますが、

Assembly Definition Filesを使えば

Aを変更した時はAだけコンパイル(Bをコンパイルしない分早くなる)

なんて事が出来るわけです。


使い方

使い方は簡単、Createの項目からAssembley Definitionを作成し、


f:id:kan_kikuchi:20180506135947j:plain



コンパイルを分けたいディレクトリに入れるだけ。


f:id:kan_kikuchi:20180506140156j:plain


ただし、Auto Referencedが有効になっていると毎回コンパイル対象になるのでオフにしておきましょう。

f:id:kan_kikuchi:20210313084001j:plain


これだけでコンパイルが別に行われるようになり、コンパイル時間を短縮出来るようになります。


f:id:kan_kikuchi:20180506140410j:plain


また、スクリプトがどのアセンブリに属しているかはAssembly Informationで確認出来ます。

なお、デフォルトではAssembly-CSharp.dllと表示されます。


f:id:kan_kikuchi:20180506141142j:plain
f:id:kan_kikuchi:20180506141149j:plain



このように簡単に使えますが、一つ注意が必要なのが

アセンブリを分けたもの同士のスクリプトはデフォルトでは参照出来ません。


例えば以下のようにAとBでアセンブリを分けた場合、


f:id:kan_kikuchi:20180506141547j:plain


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;
  }
}

f:id:kan_kikuchi:20180506141720j:plain


こんな時はBのアセンブリにはAのアセンブリが必要だよ!という事を設定します。

設定の仕方はBのDefinition FilesのReferencesに、AのDefinition Filesを登録するだけ。


f:id:kan_kikuchi:20180506142636j:plain


ただし、BにはAが必要だし、AにもBが必要みたいな依存しあってる設定には出来ません。


なお、アセンブリを分けてない(Assembly-CSharp.dllに属している)スクリプトから

アセンブリを分けたスクリプトを参照する事は問題ありません。

以下の例だと、CからAやBを参照する事は可能です。(逆は駄目)


f:id:kan_kikuchi:20180506142244j:plain


おわりに

依存関係を設定し始めると、かなりごちゃごちゃして余計な手間が増えそうなので、

依存関係を設定せずに済むようなものだけを別コンパイルにするのが、楽な使い方になりそうです。


なお、プラットフォーム毎にコードを分けたりも出来るようです。



------------追記------------


コンパイル時間の短縮を図るタイミングを決めるための

アセンブリごとのコンパイル時間を計測したり、閾値を越えたら警告を出したりするやつを作りました!


f:id:kan_kikuchi:20181127050927j:plain



------------追記おわり------------