Search Unity

新しいアセットインポートパイプライン:アセットのインポートをスピードアップするための確固たる土台

, 11月 7, 2019

2019.3 より、新規プロジェクトにおいて新しいアセットインポートパイプラインがデフォルトで使用されます。これにより、プラットフォームの切り替えが高速になり、インポートをさらに高速化する土台が提供されるため、時間の節約につながります。また、大規模なプロジェクトに合わせて、より優れたアセットパイプラインの拡大ができるようにする作業も進めています。この記事では、新しい改善点に関する詳細や、Unity の原動力および考慮事項を紹介します。

新しいアセットをプロジェクトに配置しても、アセットインポートパイプラインでそれが検出されてインポートされるまで、プロジェクトの一部とはなりません。アセットインポートパイプラインが担うのは、プロジェクトの状態を正しく検出することと、開発者が各種 API を使用してこの状態を検出できるようにすることです。

2017 年に、アセットインポートパイプラインの書き換え作業が始まり、より堅牢かつスケーラブルなアプローチに向けて道筋をつけ始めた一方で、開発者の日常のワークフロー内で報告された数々のペインポイントへの対処も行われました。Unity 2019.3(現在ベータ版として利用可能)では、新しいアセットインポートパイプライン(別名アセットインポートパイプライン V2)が新規プロジェクトのデフォルトの実装となります。古いプロジェクトでも、この新しいシステムのメリットを活かすために、新しいアセットインポートパイプラインにアップグレードできます。

今日は新しいパイプラインの背後にある考え方をいくつか共有します。具体的には、新しいアセットインポートパイプラインにアップグレードするときにスクリプトを書き換える必要がないように、新しいシステムと既存の API の互換性を確保するために配慮したことを共有したいと考えています。

インポート時間をさらに短縮する

日常の開発サイクルは膨大な数のワークフローで構成されています。そのうち最も時間のかかる問題を特定し、それらの問題に対する解決策を実装しました。

アセットのインポートは時間がかかることがあります。ソースデータを Unity エディターなどのプラットフォームで活用できる形式に変更することは簡単な処理ではありません。たとえば、複雑な 3D モデルのインポートには大量の演算を必要とし、アニメーションが組み合わさっているとその時間はさらに長くなります。

これに対処するために、解決策の一環として検討する必要がある 3 つの概念を紹介します。

インポート結果

ほとんどの種類のアセットについて、Unity ではプロジェクトのターゲットプラットフォームに応じて、ソースファイルからデータを変換する必要があります。その結果は、互換性のある GPU 形式(PVRTC、ASTC、ETC など)によって変わります。

これは、ほとんどのファイル形式がストレージを節約するために最適化されている一方で、ゲームやその他リアルタイムアプリケーションでは、アセットデータの形式がハードウェア(CPU、グラフィック、オーディオハードウェアなど)ですぐに利用できる形式になっている必要があるためです。

たとえば、Unity で PNG 画像ファイルをテクスチャーとしてインポートするときは、実行時に元の PNG 形式のデータは使用しません。代わりに、テクスチャーがインポートされるときに、Unity ではその画像の新しい表現を別の形式で作成し、作成された画像はプロジェクトの Library フォルダーに格納されます。エンジン内の Texture クラスで使用されるのがこのインポートされたバージョンで、リアルタイムで表示するために GPU にアップロードされます。これはインポート結果と呼ばれます。

決定論的

インポートするときは、たとえ別のハードウェアを使用しているときでも、互いにまったく同じ形式の同じインポート結果が確実に得られることが重要です。私たちが「決定論的」と呼んでいるのは、同じ入力に対して同じ出力が得られる原則のことです。

依存関係の追跡

アセットインポートパイプラインは、各アセットのすべての依存関係を追跡し、すべてのアセットのインポートされたバージョンのキャッシュを保持します。アセットのインポート依存関係とは、インポート結果に影響を及ぼす可能性のあるすべてのデータのことです。これは、いずれかのアセットのインポート依存関係が変更された場合は、キャッシュされているバージョンのインポートされたアセットが古いものとなり、それらの変更を反映するにはそのアセットを再インポートする必要があることを意味します。

新しいアセットインポートパイプラインの紹介

インポート時間が長くなる状況はさまざまです。Unity では次の 2 つのワークフローを特定し、上記問題に対処するために、フレッシュなプロジェクトのインポート高速なプラットフォームの切り替えという 2 つのソリューションを実装しました。

フレッシュなプロジェクトのインポート

初めてプロジェクトをセットアップするときは、Library フォルダーが削除されている状態と本質的には同じです。これは、Assets フォルダー内のすべてのアセットが、アセットインポートパイプラインによって列挙されインポートされる必要があるということを意味します。これは本来、コストのかかる操作です。ただし、インポートプロセスが決定論的で、かつ複数のマシンにまたがって一定であるようにすることで、ソースアセットのサイズやインポート結果のサイズによっては、インポート結果を取得するのにかかる時間を大幅に短縮できます。

Unity では、新しい Unity Accelerator を使用することでこれを達成しました。Unity Accelerator では、接続している全員からのインポート結果をクラウド上にキャッシュします。これにより、アセットのインポートに伴う数多くの処理を経ることなく、インポート結果をサーバーから直接ダウンロードできます。

高速なプラットフォームの切り替え

Unity 2019.2(元のアセットインポートパイプライン)まで、Library フォルダーはアセットの GUID がファイル名となっているファイルで構成されていました。そのため、プラットフォームを切り替えると Library フォルダー内のインポート結果が無効になり、プラットフォームを切り替えるたびに再インポートする必要がありました。

アセットインポートパイプライン V1

毎日プラットフォームを何回も切り替える必要がある場合は、プロジェクトのサイズによっては、それだけで何時間もかかってしまいます。

マシン上のプラットフォームごとにそのプロジェクトのコピーを作成するなどの回避策はありますが、拡大縮小がうまく機能しないこともあります。

新しいアセットインポートパイプラインにより、ファイル名のマッピングから GUID を排除しました。アセットの依存関係は追跡されるため、それらをすべて一緒にハッシュ化して、アセットのインポート結果のリビジョンを作成できます。これにより、アセットごとに複数のリビジョンを持つことができます。これは、ファイル名のマッピングが GUID に縛られなくなったことを意味します。この要件がなくなることで、異なる設定間で機能するインポート結果が得られます。高速なプラットフォームの切り替えのためには、プラットフォームごとに 1 つのインポート結果を用意することで、プラットフォームを切り替えたり切り戻したりしたときにはすでにインポート結果がそこにある状態にします。こうすることで、アセットインポートパイプライン V1 よりプラットフォームの切り替えが大幅に速くなっています。

アセットインポートパイプライン V2

考えられるデメリット

アセットに変更を加えると、Unity では多数の新しいファイルが生成されます。これがディスクのストレージ容量を占めることになります。ただし、Unity ではこの問題に対して、Unity が再起動されたときに使用されていないインポート結果を削除する方法を取ることにしました。プラットフォームごとの最新のインポート結果は追跡されるため、古いインポート結果が削除されても高速なプラットフォームの切り替えは引き続き機能します。これにより、ディスク容量の一部が解放されます。

新しいアセットインポートパイプラインにアップグレードする方法

新しいアセットインポートパイプラインは、Unity 2019.3 ベータ版で利用できます。既存のプロジェクトがある場合は、エディターの「Project Settings」ウィンドウを使用して、新しいアセットインポートパイプラインにアップグレードできます。


バージョン 2を選択すると、このプロジェクトで新しいアセットインポートパイプラインを使用することがエディターに伝えられ、プロジェクトを再起動すると、新しいアセットインポートパイプラインのコードを使用して再インポートされます。実際に Library フォルダーを削除することはありませんが、本質的には Library フォルダーを削除するのと同じ効果をもたらします。アセットインポートパイプライン V2 を使用するように切り替えても、元のアセットインポートパイプラインからのインポート結果は削除されません。V2 では独自のフォルダー構造が作成され、インポート結果はそこに格納されるからです。

Unity 2019.2 以前で作成したプロジェクトでは、デフォルトで元のアセットインポートパイプラインが引き続き使用されます。そのようなプロジェクトを Unity 2019.3 で初めて開くときに、新しいアセットインポートパイプラインにアップグレードするオプションが表示されます。却下すると、そのプロジェクトでは引き続き元のアセットインポートパイプラインが使用されます。さらに、選択したバージョンがプロジェクトの EditorSettings.asset ファイルに格納されるので、バージョンを管理できます。

新しいアセットインポートパイプラインで作成された新しいプロジェクト

Unity 2019.3 以降で新しいプロジェクトを作成するときは、新しいアセットインポートパイプラインがデフォルトになっています。作成するすべての新規プロジェクトでそれが使用されます。

今後予定されている改善

Unite Copenhagen 2019 では、Unity のチームが 2 つの講演を行いました。私の講演では、このブログ記事で取り上げているトピックの概要を紹介しており、ご自身のアセット管理戦略で意思決定を下せるようにガイダンスを提供しています。私の同僚である Jonas Drewsen は、アセットパイプラインをさらに拡張してプロジェクトの安定性を確保することを目的とした今後予定されている機能について話しました。

Unity 2019.3 ベータ版として公開中

Unity 2019.3 ベータ版を入手し、新しいアセットインポートパイプラインをお試しください。Unity ではフォーラムを通じて皆様のご意見をお待ちしております。その他のご質問につきましては、Twitter を通じてお問い合わせください。

20 replies on “新しいアセットインポートパイプライン:アセットのインポートをスピードアップするための確固たる土台”

Sadly, at least part of the initial import is still done single-threaded, and – in the case of *.blend files – by firing up a process (!) for each imported file. For a project with roughly 300 *.blend-files weighing in at 200 MB, the editor’s import time is about 2 minutes, with simple batching this time drops to less than 10 seconds.

A very simple solution for the possible downside “storage space” is to use compression – even for image-heavy projects, the “Artifacts” folder compresses remarkably well (3-4x with lz4).

Switching versioned branches is part of my daily work too. Is the new pipeline able to speed this up? My first guess is it will not because this would mean it needs to keep imported data of files that do not exist for a period of time (different branch) unless I’m missing something.

Thanks for the work and blog-post on the import pipeline!

I have a question about “remove unused Import Results when Unity restarts”. I don’t fully understand this. When becomes an import result unused? Is this related to deleting assets from the Assets directory and the import results weren’t deleted in V1? Or is there some clever logic that even detects “this target platform specific import result wasn’t used for 28 days, I need to delete this now!”?

Yep, spam comment above again, because you still havent bothered to put a spam filter on comments section of blogs despite these being publically facing. So what, you want the outside world to see unity as a company that cant even manage spam? Add a filter already, you have one on the forum, implement one here.

Thanks for your feedback, Isaac. We do have a spam filter in place and are actively working to improve. I will be removing this spam comment and, in turn, your reply.

I really appreciate you’re trying to optimize loading speeds. Workflow speed has always been a big selling point for me. I have been a bit worried about some design-decisions last years, such as including too many packages per default on new projects, increasing loading times and complexity, and cluttering my assets view with packages. I prefer the possibility to start from a clean state, where I’m in total control, which used to be the case.

Do you see any possibility of Unity reducing project file size and file count in the future? I’ve always been a bit baffled by how a simple project with a few textures and models suddenly take up 3 Gb and include 30 000 files, making it time-consuming to backup in e.g. Dropbox.

It seems like textures occupy huge amounts of space, which I can understand if they’re re-generated as a less compressed format. However, I don’t really understand how the file count can grow so high, even if I count one extra meta file per asset.

Do you think it would be possible for Unity to store textures in a format that take up less space, at least during development? And find another way to save meta-data to assets without having to create so many files?

I understand the complexity of changing an existing system, just wanted to let you know my thoughts on workflow optimization as a long-time Unity user.

Hi hannes, you should only backup the Assets, Packages and ProjectSettings folders, and possibly use GIT, instead of dropbox

Will this affect the “Local Identifier In File” GUID? We use that property to track the persistant GUID of each GO (using the Transform’s GUID).

If so, will Unity expose access to a more robust persistant GUID system for us to use?

It will not affect the behaviour of local identifier in file.

That said Unity 19.3 now has GlobalObjectIdentifier which is very useful for uniquely identifying a specific object with a stable persistent ID.

hi – will this be coming to 2019.2 pls?
we need to support iOS9 and 2019.3 is iOS10 only. thx

Once a version is released, only bugfixes are added to the version. We don’t backport new features.

Hi Warren,
iOS 9 market share worldwide has been shrinking to such a low level that it doesn’t make sense for us to continue supporting some optimizations & workarounds that were in Unity for this specific version. We can clean up the code and focus our attention to the newer versions.

Comments are closed.