Note: 本ガイドのオブジェクトとアセットの用語は Unity の public API
の命名規則と異なることがあります。
このガイドでオブジェクトと呼ぶデータは、AssetBundle.LoadAsset や Resources.UnloadUnusedAssets など Unity の public API では Assets と呼ばれています。本ガイドで Assets と呼ぶファイルが、public API でそのように表現されることは稀です。
通常、AssetDatabase や BuildPipeline などのビルド関連のコード内でのみです。それらの場合、これらファイルは public API ファイルと呼ばれます。
テキストエディターを使用してマテリアルに関連づけられた .meta ファイルを開きます。ファイルの上のほうに "guid" Local ID を見つけるには、テキストエディターでマテリアルファイルを開きます。マテリアルオブジェクトの定義は以下のようになっています:
--- !u!21 &2100000
Material:
serializedVersion: 3
... more data …
上述の例では、「&」ではじまる数字はマテリアルの Local ID です。このマテリアルのオブジェクトがファイル GUID「abcdefg」で識別されているアセット内にあったなら、マテリアルのオブジェクトはファイル GUID「abcdefg」+Local ID「2100000」の組み合わせで一意に識別されます。
2.3 なぜファイル GUID とローカル ID か?
なぜ Unity の File GUID と Local ID の仕組みが必要なのでしょうか? その答えは、堅牢性とプラットフォームに依存しない柔軟なワークフローを提供するためです。
File GUID と Local ID は堅牢ですが、GUID の比較は時間がかかり、実行時にはよりパフォーマンスの高いシステムが必要になります。Unity は File GUID と Local ID を単純なセッション固有の整数に変換するキャッシュを内部的に維持しています。(このキャッシュは内部的に PersistentManager と呼ばれています)これらの整数は Instance ID と呼ばれ、新しいオブジェクトがキャッシュに追加されると単純な一本調子で増加する番号を割り当てられます。
キャッシュはオブジェクトのソースデータの位置を定義する Instance ID、File GUID, Local ID とメモリ上のオブジェクトのインスタンス(存在する場合)の間のマッピングを保持します。これにより、UnityEngine.Objects はお互いの参照を強固に維持することができます。
Instance ID の参照を解決すると、その Instance ID で表されるロードされているオブジェクトを素早く返却することができます。対象のオブジェクトがまだロードされていないときは、File GUID と Local ID でオブジェクトのソースデータを解決することで、ジャストインタイム(必要なものを、必要なときに、必要なぶんだけ)ロードすることができます。
実装上の注意として、実行時には、上述の制御フローは文字通り正確ではないです。実行時に File GUID と Local ID を比較しても十分なパフォーマンスは得られません。Unity プロジェクトを構築する際には、File GUID と Local ID はより単純な形式でマッピングされます。しかし、概念は変わらないので、File GUID と Local ID の観点であれば、実行時の有用なアナロジーであることに変わりありません。(これは、アセットの File GUID は実行時に問い合わせできない理由でもあります)
オブジェクトはスクリプトで明示的にロードすることもできます。オブジェクトを作成するか Resource-Loding API(AssetBundle.LoadAsset など)を呼び出してロードします。オブジェクトがロードされると、Unity は各参照の File GUID と Local ID を Instance ID に変換することで参照の解決をテストします。
最初に Instance ID が参照されたとき、2つの基準が true ならオブジェクトはオンデマンド(ユーザー要求があった際にその要求に応じてサービス提供をすること)でロードされます:
Instance ID は、現在ロードされていないオブジェクトを参照している
Instance ID はキャッシュに登録されている有効な File GUID と Local ID がある
通常だと、参照自体がロード/解決した直後に発生します。
File GUID と Local ID が Instance ID を持たない、または、ロードされていないオブジェクトの持つ Instance ID が無効な File GUID と Local ID を参照している場合(参照は保存されますが)実際のオブジェクトはロードされません。
Resources フォルダーから取得したオブジェクトは、Resources.UnloadAssetAPI を呼び出すことで明示的にアンロードすることができます。これらのオブジェクトの Instance ID は有効なままなので、有効な File GUID と Local ID が含まれますが、Mono 変数などのオブジェクトが Resources.UnloadAsset でアンロードされたオブジェクトへの参照を保持している場合、そのオブジェクトは参照のいずれかが逆参照されるとすぐに再ロードされます。
AssetBundle.Unload(true)API を呼び出すと AssetBundle からソースを取得したオブジェクトは自動的にアンロードされます。これによって、オブジェクトの Instance ID の File GUID と Local ID が無効になり、アンロードされたオブジェクトの参照は (missing) になります。C#スクリプトからアンロードされたオブジェクト、メソッド、プロパティにアクセスすると NullReferenceException が発生します。
AssetBundle.Unload(false) が呼び出されたときは、アンロードされた AssetBundle からソースを取得したオブジェクトは破棄されませんが、Unity はその Instance ID の File GUID と Local ID 参照を無効にします。オブジェクトが後でメモリーからアンロードされ、アンロードされたオブジェクトの参照が残っている場合、Unity はオブジェクトをリロードすることができません。
注意:実行時にオブジェクトがアンロードされずにメモリーから削除される最も一般的なケースは、Unity がグラフィックコンテキストの制御を失ったときに発生します。これは、モバイルアプリがサスペンドされ、アプリが強制的にバックグラウンドに移行されたときに発生することがあります。この場合、モバイル OS は、GPU メモリーからすべてのグラフィックリソースを削除してしまいます。アプリがフォアグラウンドに戻ってきたときに、シーンのレンダリングを再開するまえに、Unity は必要なすべてのテクスチャ、シェーダ、メッシュを GPU に再ロードしなければいけないです。
AssetBundle のドキュメントで説明されているように、このインデックスにはシリアル化されたルックアップの木構造(lookup tree)が含まれているので、これを使用してオブジェクトの名前から File ID と Local ID を解決します。また、シリアル化されたファイルの中の特定のバイトオフセットからオブジェクトを見つけるためにも使用されます。
COSMO のメンバーであり、DysonSphere Program のパイオニアであるあなたは、未知への旅に出るメカを端末を使って操作しましょう。そして、リソースを収集して、生産ラインを計画・設計し、徐々に完全な自動化を実現することを、ゼロから出発します。小さなワークショップから壮大な銀河の中の産業帝国へと発展させ、最終的には偉大な神託の地、DysonSphere を築きましょう。