テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】ソースコード変更後のコンパイル時間を短く抑える

今回はC#のビルド時間を短くする方法についてです。f

C#コンパイル

Unityでゲームを開発する上で、コンパイル時間は必ず発生します。例えばソースコードを少し変えてからUnityエディタに戻ると、右下に処理マークが出てきます。

f:id:tsubaki_t1:20160724230824j:plain

これ、規模が小さいならばそれほど気にならないのですが、costを使用していたり規模が大きくなり複雑になってくると、非常に長い時間を要求してきます。
これでは何度もコードを修正しながら開発出来ません。

今回はその辺りを何とかする方法について考えてみます。

 

Assembly Definition Filesを使用する

Unity公式のこの問題を解決する手段です。

Unity 2017.3から利用可能です。

tsubakit1.hateblo.jp

 

Pluginsフォルダにあるコードは、事前コンパイルされるのを活用

まず思いつくのが、Pluginsフォルダに既にfixした(自身が触らない)コードを配置してしまう事です。Standard Assetsフォルダでも可。

PluginsフォルダやStandard Asstesフォルダ以下に配置したアセットは、通常のコードよりも先にコンパイルされます。また、コンパイルが不要な場合はコンパイルされません。*1

f:id:tsubaki_t1:20160724231327j:plain

なので、確定したコード群はサクっとpluginsフォルダに移動することで、現在編集中のコード部分のコンパイル時間分は短縮出来ます。

 

事前にDLLにコンパイルしたコードを使用する

次点で思いつくのが、コードを事前にDLL化してしまう事です。

コードをコンパイルし既にDLL化しているのであれば、コンパイル時間はまぁ減るだろうという目論見となります。

f:id:tsubaki_t1:20160725224755j:plain

 

コンポーネントをDLL化すると、参照が外れる

まずひとつ目は、元々Assetsフォルダ以下に配置したコードをDLLに変換する場合、dll化する事で参照が剥がれてしまう事です。

例えばC#にてコードを作成し、プレハブを作成していた場合、DLL化に伴いGUIDが変化するためmissingになってしまいます。

f:id:tsubaki_t1:20160725225751j:plain

対策というか、自分のコレに対する基本的な考えは、コンポーネントをDLL化しない事です。

コンポーネントはDLL化せず、コンポーネントはUnityとの接点・DLLは機能に集約するような感じの実装してるなら、多分問題にはならなそうです。

 

もう一つの対策は、変化したGUIDを元に再設定する方法です。

field idとguidを差し替えてやれば、prefabやsceneに設定したコードの参照先を差し変わります。

f:id:tsubaki_t1:20160725231058j:plain

field idとguidは 【Unity】AssetBundleのManifestファイルに書かれている内容について で紹介した変換を使えば取得出来なくはないですが、手っ取り早いのは指定のコンポーネントをプレハブに設定してfield idとguidを確認する事です。

 

なおPluginsに移動する手法の場合、その辺りの心配は要りません。

DLLの作り方

以前に書いてますが、改めて書き直しておきます。Monodevelopを使用しています。

  1. メニュー > File > 新規 > ソリューションを選択
  2. C# >ライブラリを選択。
    プロジェクト名は、まぁ適当に。

    f:id:tsubaki_t1:20160725232033j:plain

  3. プロジェクト > (プロジェクト名)のオプションを選択
    ビルド > 一般のTarget Frameworkを.NET 3.5に設定

    f:id:tsubaki_t1:20160725232444j:plain

  4. ビルド > 出力の出力パスを、Assets以下にでも指定しておく

  5. もしUnityのAPI群にアクセスしたい場合、参照にUnityEngine.dll等を追加する。
  6. もしUnityEngine.DLL等をプロジェクトに含めるなら、参照のローカルコピーは外しておく。

    f:id:tsubaki_t1:20160725233202p:plain

コレでコンパイルすると、出力パスを指定したフォルダにdllが生成されます。

 

コマンドラインを使用した方法もありますが、個人的にはデバッグが容易なコチラの方が気に入っています。

 

mdbファイルがあればデバッグも可能

dll化する事でソースコードが見られなくなります。DLL化したコードが何らかの問題を起こした際にも、非常に追いにくいです。

 実際にはmdbがdllの隣にあれば、dllの中でもブレークポイントを貼る事が可能です。

f:id:tsubaki_t1:20160725234222p:plain

dllを配置後プロジェクトを動かしていなければ、デバッガにてエラーを起こしたコードへジャンプなり、ブレークポイントなりを設定・追跡出来ます。

 

またブレークポイントを設定したい場合、ブレークポイントを設定したいコードをUnityと接続しているMonodevelopで表示して、ブレークポイントを設定すれば出来ます。

f:id:tsubaki_t1:20160725234830g:plain

 

pdbmdb

この記事、元々windowsでやっていたのですが、途中からmacに変更しています。これはwindowsコンパイルするとpdbが作られmdbが作られない為です。

一応pdb2mdbなる物で変換出来るそうなのですが少し試した感じ上手く動かなかったので一旦放置で。

d.hatena.ne.jp

 コンパイル後のdllからビルド前のコードにはアクセス出来ない

pluginsフォルダの手法も事前コンパイルの手法も共通した注意点があります。それはコンパイル後のコードはコンパイル前のコードにアクセス出来ないという事です。

例えばpluginsフォルダの場合、assetsフォルダに配置したスクリプトはpluginsフォルダに配置したスクリプトにアクセスが可能です。しかし、plusingsフォルダに配置したスクリプトからassetsフォルダに配置したアセットへアクセスする事は出来ません。

関連

 

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

docs.unity3d.com

tsubakit1.hateblo.jp

*1:5.3系で不具合があり、コンパイルされてたが、5.3.7でfix