Version: 2021.2
言語: 日本語
アセットデータベース
AssetDatabase によるバッチ処理

アセットデータベースの更新

Unity は以下の場合にアセットデータベースを最新情報に更新します。

  • Unity エディターが再びフォーカスを取得したとき (Preferences ウィンドウで Auto-Refresh を有効にしている場合)
  • メニューから Assets > Refresh を選択したとき
  • C# から AssetDatabase.Refresh を呼び出したとき

他の AssetDatabase API は Refresh() を呼び出しますが、指定したアセットに対してのみです。例えば CreateAsset()ImportAsset() などがそうです。

Unity はアセットデータベースの更新中に以下の手順を実行します。

  1. アセットファイルに対する変更を探し、ソースアセットデータベースを更新します。
  2. .dll、.asmdef、.asmref、.rsp、.cs ファイルなどのコード関連ファイルをインポートしてコンパイルします。
  3. スクリプトから Refresh が呼び出されなかった場合は、ドメインをリロードします。
  4. インポートされたコード関連ファイルのすべてのアセットを後処理します。
  5. 次に、 コードに関連しないアセットをインポートし、インポートしたアセットの残りすべてを後処理します。
  6. その後、アセットを ホットリロード します。

アセットデータベースの更新処理

Unity はアセットデータベースの更新中に前のセクションで説明した手順を実行します。このセクションでは、このプロセスについて詳しく説明します。これらの処理は更新ループ内で発生します。いくつかのステップが更新プロセスによって再起動する場合があります (例えば、アセットのインポートによって Unity がインポートする必要がある他のアセットを作成します)。

Unity は、以下の条件でアセットデータベースの更新ループを再起動をします。

  • インポート後に、インポーターが使用したファイルがディスク上で変更された場合。
  • OnPostProcessAllAssets で以下のいずれかを呼び出す場合
  • インポートされているファイルのタイムスタンプがインポート中に変更された場合、ファイルは再インポートのためにキューに加えられます。
  • インポーターがインポートの途中でファイルを作成する場合 (例えば、FBX モデルは、モデルからテクスチャを抽出する更新をして再起動します)。

ディスク上の変更の検索

Unity はディスク上の変更を検索するとき、プロジェクトの AssetsPackages フォルダーをスキャンし、前回のスキャン以降にファイルが追加、変更、削除されていないか確認します。変更をリストにまとめ、次のステップで処理します。

ソースアセットデータベースを更新

Unity がファイルリストを収集すると、追加または変更されたファイルのファイルハッシュを取得します。次に、それらのファイルの GUID でアセットデータベースを更新し、削除されたことが検出されたファイルの記録を削除します。

依存関係の追跡

アセットデータベースは、 静的依存関係動的依存関係 の 2 種類のアセット依存関係を追跡します。アセットの依存関係が変更されると、Unity はそのアセットの再インポートをトリガーします。

静的な依存関係

静的依存関係は、インポーターが依存する値、設定、 プロパティです。静的な依存関係はアセットがインポートされる前に認識され、インポート処理の間、インポーターの動作には影響されません。アセットの静的依存関係が変更されると、Unity はそのアセットを再インポートします。

一般的な静的依存関係の例は以下のとおりです。

  • アセットの名前
  • アセットに関連付けられたインポーターの ID
  • インポーターのバージョン
  • 現在選択されているビルドターゲットプラットフォーム
動的な依存関係

Unity は通常、インポート処理の間にアセットの動的依存関係を検出します。これは、これらの依存関係がソースアセットのコンテンツによって定義されているためです。例えば、シェーダーが別のシェーダーを参照したり、プレハブが他のプレハブに依存する場合などがその例です。

インポーターは、ソースアセットのコンテンツに基づいて、条件付きでグローバル状態を使用する場合もあります。その場合、動的依存関係になります。この例としては、ターゲットプラットフォーム、プロジェクトの色空間、グラフィックス API、スクリプトのランタイムバージョン、テクスチャの圧縮状態などがあります。

Unityは、アセットのこれらの動的な依存関係を、Asset Import Context に保存します。

コード関連ファイルのインポートとコンパイル

変更または追加されたファイルのリストで、Unity はコードに関連するファイルを収集し、それらをスクリプトコンパイルパイプラインに送信します。コンパイラーは、プロジェクトのスクリプトファイルとアセンブリ定義ファイルからアセンブリを生成します。この手順の詳細は、スクリプトコンパイルアセンブリ定義ファイル を参照してください。

ドメインを再ロード

Unity はスクリプトの変更を検出すると、C# ドメインを再ロードします。これは、新しい Scripted Importer が作成された可能性があり、そのロジックが更新キューのアセットのインポート結果に影響を与える可能性があります。この手順によって Refresh() が再起動され、新しい Scripted Importer が有効になります。

コードに関連しないアセットをインポート

Unity がすべてのコード関連アセットをインポートし、ドメインを再ロードすると、残りのアセットに移ります。各アセットのインポーターはそのタイプのアセットを処理し、インポートするファイルタイプをファイル名の拡張子に基づいて識別します。例えば、TextureImporter は .jpg、.png、.psd ファイルなどをインポートします。

インポーターには以下の 2 つのタイプがあります。

Unityは、すべてのネイティブインポーターを最初に処理し、次にすべてのスクリプトインポーターを別の段階で処理します。

インポーターがアセットファイルをインポートすると、Unityは AssetImportContext を生成します。AssetImportContext は、アセットの静的依存関係を報告します。

また、インポート処理中に、いくつかのコールバックが発生します。

Asset Importer の呼び出しを前処理します。

アセットインポーターの呼び出しを後処理します。

すべてのインポートが完了するとトリガーされる最後の後処理のコールバックは OnPostprocessAllAssets です。

Asset フォルダーの更新処理を再起動すると多くのことが起こります。以下のような例があります。

  • アセットのインポートに失敗した場合

  • 更新のインポートフェーズ中にアセットが変更された場合。例えば、リスト内のファイルが変更されたために、その変更日が前回の更新時にあった日付と異なる場合などです。これは、エディターにフォーカスがあるときに、バージョン管理システムからファイルの抽出を開始すると発生します。

  • インポート中にアセットが他のアセットを作成した場合。例えば、FBX をインポートするとき、テクスチャは FBX から抽出されてプロジェクトに配置されます。つまり、Unity はテクスチャ (およびテクスチャが生成するアーティファクト) をインポートする必要があります。

  • 前処理/後処理のコールバック中、または OnPostProcessAllAssets 内で AssetDatabase.ForceReserializeAssetsAssetImport.SaveAndReimport を使ってファイルの再インポートを強制する場合。これを行う場合は、無限再インポートループを引き起こさないように注意する必要があります。

  • スクリプトのコンパイル後にアセンブリの再読み込みが発生した場合。更新処理中に C# ファイルを生成する場合は、その新しいファイルをコンパイルする必要があるため、Unity は更新して再起動します。

  • アセットを “Text only” (テキストのみ) として保存しているにもかかわらずバイナリとしてシリアル化する必要がある場合は、 再起動が発生します。(例えば、Terrain (地形) を含むシーンは、バイナリとしてシリアル化する必要があります。なぜなら、地形データは、テキストファイルの文字の配列として表示すると扱いにくいからです。)

ホットリロード

ホットリロード (hot reload) とは、エディターが開いている間に Unity がスクリプトやアセットに変更をインポートして適用する処理のことです。これは、エディターが再生モードまたは再生モード以外の間に発生する場合があります。変更を有効にするためにアプリケーションやエディターを再起動する必要はありません。

スクリプトを変更して保存すると、Unity はプロジェクトのすべてのスクリプトデータをホットリロードします。まず、ロードされたすべてのスクリプトのシリアル化可能な変数の値をすべて保存し、スクリプトを再ロードしてから値を再興します。シリアル化できない変数に保存されているデータは、ホットリロードの際にすべて失われます。

ノート: Unity は、最初に ビルトインのデフォルトインポーター でアセットをインポートし、次に、スクリプトアセットをインポートします。そのため、デフォルトのアセットに対して、スクリプトで定義された PostProcessAllAssets は呼び出されません。

更新の終了

これらの手順がすべて完了すると、Refresh() が完了します。アーティファクトデータベース が関連情報によって更新され、必要なインポート結果のファイルがディスクに生成されます。

アセットデータベース
AssetDatabase によるバッチ処理