原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】Assembly Definitionを利用してコンパイル時間を短縮する

花粉症(秋)

毎年恒例の花粉症の季節が始まり日常業務に支障をきたしているのにも関わらず周囲からはあまり理解されない不憫属性持ちの皆さんこんにちは。春と比べて秋の方は情報が少なく何も知らないまま急に症状が始まるので大変です。しかも最近はインフルエンザが流行していおり、公共の場で少しでもくしゃみをしようものなら周囲から一斉に非難の視線を浴びてしまうので本当に勘弁してほしい。

 

コンパイル時間

Unityでゲーム開発を行っていると、ゲームの規模が大きくなるにつれてコードを変更した後の待ち時間(コンパイル時間)が問題になってきます。
待ち時間中にはドメインリロード(staticフィールドのリセット等)も行われているため、ある程度の時間が掛かるのは仕方ないかもしれませんが、あまりに長くなると開発全体の効率に悪影響を及ぼすため出来れば短縮したいものです。

コンパイル時間を短縮するにはコードを最適化する、スクリプトの数を減らす等の対処が最初に取られますが、それでも尚コンパイルに時間が掛かる場合にはAssembly Definitionという機能を利用してコンパイルの範囲を限定し、該当するアセンブリ(dll)のみをコンパイルする=全体のコンパイル時間を短くする、という手法も有効です。

docs.unity3d.com

 

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の導入以後の開発でコンパイル時間を短縮することを意識して開発できるようになります。
これはプロジェクトの規模が大きくなればなるほど恩恵は大きくなるため、一度導入を検討してみてはいかがでしょうか。

 

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。