
花粉症(秋)
毎年恒例の花粉症の季節が始まり日常業務に支障をきたしているのにも関わらず周囲からはあまり理解されない不憫属性持ちの皆さんこんにちは。春と比べて秋の方は情報が少なく何も知らないまま急に症状が始まるので大変です。しかも最近はインフルエンザが流行していおり、公共の場で少しでもくしゃみをしようものなら周囲から一斉に非難の視線を浴びてしまうので本当に勘弁してほしい。
コンパイル時間
Unityでゲーム開発を行っていると、ゲームの規模が大きくなるにつれてコードを変更した後の待ち時間(コンパイル時間)が問題になってきます。
待ち時間中にはドメインリロード(staticフィールドのリセット等)も行われているため、ある程度の時間が掛かるのは仕方ないかもしれませんが、あまりに長くなると開発全体の効率に悪影響を及ぼすため出来れば短縮したいものです。
コンパイル時間を短縮するにはコードを最適化する、スクリプトの数を減らす等の対処が最初に取られますが、それでも尚コンパイルに時間が掛かる場合にはAssembly Definitionという機能を利用してコンパイルの範囲を限定し、該当するアセンブリ(dll)のみをコンパイルする=全体のコンパイル時間を短くする、という手法も有効です。
Assembly-CSharp
というのも、Unityでプロジェクト内にスクリプトを追加すると、そのスクリプトは全てAssembly-CSharp.dllへビルドされるようになります。
いわゆる「全部入り」のアセンブリが肥大化する形となり、その為、一部のコードを修正しただけでも「全部入り」のアセンブリがコンパイル・ビルドされるので、スクリプトの数が増えればその分だけコンパイル時間の増加につながります。
そこでUnityではAssembly Definitionを利用する事でAssembly-CSharp.dllのビルド範囲から分離してコンパイル先のアセンブリ(dll)を定義できるようになっています。

この機能はAssembly Definition Files(以後、adf)にビルド範囲と出力先アセンブリ等を指定する事で実現しますが、手順としてはこのadfを分割したいスクリプトが格納されたディレクトリ直下に作成するだけです。

Createメニューから「Assembly Definition」を選択する
adfを作成するとその下にあるディレクトのスクリプトも全てadf定義のアセンブリ(dll)へビルドされる事になります。

adfが存在するカレントとその下のスクリプトが分割対象となる
逆に言うと、adfを作成する前準備としてスクリプトを分割したいアセンブリ単位にディレクトリを作成して格納しておく必要があります。
参照設定
C#を使ったプロジェクトでは一般的な事ですが、アセンブリ(dll)を分割するという事は現状のスクリプトで分割したスクリプトの関数等を参照している部分がある場合は参照設定を設定し直す必要が出てきます。
Unityでは幸いながら「全部入り」のAssembly-CSharpへビルドされるスクリプトに関しては、adfによって分割されたアセンブリ側の定義で「Auto Referenced」という設定を有効にしておくと自動的に参照設定が行われる為、特に変更する必要はありません。

逆に分割する側のスクリプトに「全部入り」のAssembly-CSharpへビルドされるスクリプトの関数を参照してる箇所がある場合は参照不可でビルドエラーとなります。

そう言った場合は分割したアセンブリ同士は参照可能なので、参照先のスクリプトもadfを定義することで別のアセンブリとして、それをadfの参照定義に追加する作業を行います。
これはアセットストアで購入したアセットのスクリプトやPackageManagerからインストールした外部パッケージのスクリプトを参照しているときも同様です。
例えば分割したアセンブリのスクリプトがUniTaskを利用している場合は、adfのInspectorを開きAssembly Definition Referencesの項目にUniTaskのアセンブリを設定することになります。(これが結構面倒くさい)

赤枠内の設定がアセンブリの参照設定
分割されたアセンブリは全てAssembly-CSharp.dllと同じディレクトリにadfと同じファイル名でdllが作成されます。分割前と分割後ではAssembly-CSharp.dllのサイズに大きな差が出るのが分かると思います。

コンパイル時間を短縮するには
前述のように結構面倒な作業が必要となるアセンブリの分割ですが、実はただadfで分割しただけではコンパイル時間に大きな変化はありません。
なぜならアセンブリを分割しても「Auto Referenced」の設定により参照設定が行われていると、「全部入り」のAssembly-CSharpの方もコンパイル対象となるからです。
この為、「全部入り」のAssembly-CSharpから完全に参照されない形にすることを意識して、できるだけ「Auto Referenced」をOFFにできるようなアセンブリの分割を行うようにしましょう。(なかなか難しいけど)
まぁ、私の場合はデバッグ&動作確認用のテストスクリプトが多くて、それを分割するだけでもメリットがありましたが。
また、ソースコード内の依存関係をシステムとして導入することなるので、Assembly Definitionの導入以後の開発でコンパイル時間を短縮することを意識して開発できるようになります。
これはプロジェクトの規模が大きくなればなるほど恩恵は大きくなるため、一度導入を検討してみてはいかがでしょうか。