Addressable Assets System

##五、Addressable Assets Systemの概要

Unityは2018バージョンでAddressableAssets Systemのプレビューバージョンをリリースし、2019バージョンは公式バージョンになり、本番環境に移行できるようになりました。しかし実際には、私たちは早期採用者であり、その過程で多くの落とし穴に遭遇しました。落とし穴に入ったとき、Addressable Assets Systemはまだバージョン0.8でしたが、現在は1.3.3です。したがって、以降のコンテンツは最新バージョン1.3.3に基づいています。
Addressable Assets Systemは、文字通りにAddress可能なAssetsシステムを意味します。目的は、アセットを識別可能なAddressIDでバインドし、内部GUIDを介してアセットを管理することです。 5.X以降のアセットタグに触発されるべきであり（実際、かなり前にアセットストアに同様のBundlesプラグインがありました）、AssetBundlesは最終的に管理および生成されますが、これは実際には本質的な違いではありません。
Addressable Assets Systemは、次の2つの部分で構成されています。
（1）Address指定可能な資産ウィンドウ。
（2）スクリプト化されたビルド。
公式の観点からは、[Addressable Assets]ウィンドウがプライマリであり、スクリプト化されたビルドがセカンダリです。ただし、実際に使用した後は、多少説明がずれている場合があります。 [Addressable Assets]ウィンドウは開発中のアセットの管理と調整に使用され、スクリプト化されたビルドは自動ビルドに使用されます（[Addressable Assets]ウィンドウはボタン操作も提供できます）。
###5.1 Addressableをインストールする

Addressableは、Package Managerからダウンロードできます。以下のように示しています。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ea5e28ef-d10f-ddd5-d965-952cd81a3700.png)


注意：Addressable Asset Systemの実装環境はUnity2018.3以降である必要があります。PackageManagerに慣れていない場合は、公式ドキュメントを参照してください。
###5.2知っておくべき用語

Addressable Assets Systemシステムを説明する前に、いくつかの用語や概念を理解する必要があります。
>（1）Address：ランタイムインデックス作成用のAssetロケーション識別子。
（2）Addressable Asset Dataディレクトリ：プロジェクト内のすべてのAddressable Assetのメタデータを保存します。プロジェクトのAssetsディレクトリにあります。
（3）Asset Group：ビルド時に処理できるAddressable Assets。
（4）Asset Group Schema：生成中にGroupに割り当てて使用できるデータのグループを定義します。
（5）AssetReference：直接参照に似ていますが、初期化されるオブジェクトを遅延にします。AssetReferenceオブジェクトは、GUIDを必要に応じてロードできるAddressableなGUIDとして格納します。
（6）Asynchronous loading：ゲームコードを変更せずに、開発中にAssetの場所とその依存関係を変更できます。非同期ロードは、Addressable Assets Systemの基本的な実装です。
（7）Build script：Asset Groupプロセッサを実行してAssetsをパッケージ化し、AssetsマネージャーにAddressとAssetsの場所の間のマッピングを提供します。
（8）Label：実行時に類似項をロードするための追加のAddressable Asset識別子を提供します。たとえば（Addressables.DownloadDependenciesAsync(“spaceHazards”);）。

###5.3Addressable Assetsを準備する方法

Address可能なAssetsの準備は、大きく2つの部分に分けられます。1つはAssetsの識別、もう1つはAssetsの構築です。

####5.3.1Address可能な資産の特定

UnityEditorでAssetsをAddressableとしてマークする方法は2つあります。
>（1）Object’s Inspector
（2）Addressablesウィンドウ

**5.3.1.1Inspectorウィンドウの使用**
“Project”ウィンドウで、Assetを選択してそのInspectorを表示します。Inspectorで、「Address」チェックボックスをクリックして、希望の名前を入力します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/a60bb653-fed4-7a3d-8782-6449efbcdb2a.png)


**5.3.1.2Addressableウィンドウの使用**
Window > Asset Management > Addressablesで、Addressablesウィンドウを開きます。識別したいassetをProjectウィンドウから、AddressablesにビルドされたAddressables Groupsにドラッグします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/71e2cc6b-88dc-f723-38aa-35a02b57f1a0.png)


####5.3.2アドレスの指定

デフォルトのAddress名は、このAssetsからAssetsディレクトリへの相対パスです（例：Assets / images / myImage.png）。Assetsのアドレス名をAddressablesから変更する場合は、Assetsを右クリックしてRenameを選択します。
Addressable Assetsを初めて使用する場合、システムはプロジェクトの編集時および実行時の構成Assetsを自動的に作成します。ディレクトリはAssets / AddressableAssetsDataです。これらのディレクトリをバージョン管理に追加することをお勧めします。

####5.3.3Address可能なコンテンツの構築

APPをビルドする前に、Addressables Asset Systemは、構成済みのAssetsコンテンツを実行時に使用できる形式にパッケージ化する必要があります。ただし、この手順は自動ではありません。Editorパネルまたはシステムが提供するAPIを介して操作できます。
>（1）EditorがAddressableウィンドウを開き、Select Build > Build Player Contentを選択します。
（2）APIはAddressableAssetSettings.BuildPlayerContent（）を使用します。

###5.4Addressable Assetsの使用方法

####5.4.1アドレスによるロードまたはインスタンス化

実行時にAddressable Assetをロードまたはインスタンス化できます。あるAssetが読み込まれると、そのすべての依存関係がメモリに追加されます。そのため、Assetsを通常どおりに使用できます。ただし、これによってAssetsが自動的にSceneに配置されるわけではないため、自分でインスタンス化する必要があります。 Addressablesが提供するインスタンス化インターフェースを呼び出すと、これらのAssetsが読み込まれ、すぐにSceneに追加されます。
スクリプトからAssetsにアクセスする場合は、string型のAddressを指定する必要があります。次に、UnityEngine.AddressableAssets名前空間で次のメソッドを呼び出します。
>（1）Addressables.LoadAssetAsync（ “AssetAddress”）;指定されたアドレスにあるAssetsをロードします。
（2）Addressables.InstantiateAsync（ “AssetAddress”）;指定されたアドレスにあるAssetsをインスタンス化し、Sceneに追加します。

注：LoadAssetAsyncとInstantiateAsyncはどちらも非同期操作です。アセットのロードをコールするロジックに、コールバック関数を提供する必要があります。ロードが完了すると、このコールバック関数をコールします。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ba6c8ecc-81c7-afea-56a8-36823b8743a8.png)


**5.4.1.1 ###Sub-AssetsとComponents**
Sub-AssetsとComponentsは、Assetsロードの特殊なケースです。
>（1）Components：現在、Addressableを介してGameObjectを直接ロードできないComponentsです。GameObjectをロードまたはインスタンス化する必要があります。その後、コンポーネント参照を検索します。Addressableを拡張してコンポーネントのロードをサポートする方法については、ComponentReferenceの例を参照してください。
（2）Sub-Assets：このシステムはSub-Assetsのロードをサポートしていますが、特別な文法が必要です。Sub-Assetsの例には、sprite sheetのspriteやFBXファイルのAnimation Clipsが含まれます。spritesを直接ロードする例については、spritesのロード例を参照してください。
Address：https：//github.com/Unity-Technologies/Addressables-Sample/tree/master/Basic/Sprite%20Land

AssetsからSub-Objectをロードするには、次のAPIを使用できます。
Addressables.LoadAssetAsync <IList>（ “MySpriteSheetAddress”）;
 
個々のSub-Objectをロードする場合は、次のようなものを使用できます。
Addressables.LoadAssetAsync（ “MySpriteSheetAddress [MySpriteName]”）;
Assetsで使用可能な名前は、メインのAddressablesGroupエディターウィンドウで表示できます。さらに、AssetReferenceを使用して、Assetsのサブオブジェクトにアクセスできます。

###5.4.2 ## AssetReferenceクラスの使用

AssetReferenceクラスは、アドレスを知らなくてもAddressable Assetsにアクセスする方法を提供します。次の手順を実行できます。
>1.SceneのHierarchyインターフェースまたはProjectインターフェースからGameObjectを選択します。
2.Inspectorインターフェイスで、Add Componentボタンをクリックし、Componentsタイプを選択します。シリアル化可能なComponentsはすべて、AssetReference変数（ゲームスクリプト、ScriptableObject、その他のシリアル化可能なクラスなど）をサポートできます。
3.ComponentsにpublicAssetReference変数を追加します（たとえば、public AssetReference explosion;）。
4.Inspectorで、オブジェクトにリンクするAddressable Assetを選択します。これは、AssetsをProjectウィンドウからpublic AssetReferenceフィールドにドラッグするか、プロジェクトで以前に定義したAddressable Assetsのドロップダウンリストから選択します（下図のように示す）。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/89bb463b-a51d-4d53-3079-02c4739ca40b.png)


 
AssetReferenceをロードまたはインスタンス化するには、対応するメソッドをコールします。例えば：
AssetRefMember.LoadAssetAsync（）;
また
AssetRefMember.InstantiateAsync（pos、rot）;
注：通常のAddressable Assetsと同様に、LoadAssetAsyncとInstantiateAsyncは非同期操作です。Assetsのロードが完了したときにコールするためのコールバックを提供できます（詳細については、Async operation handlingセクションを参照してください）。
Sub-Assets（SpriteAtlasやFBXなど）を含むAssetsをAssetReferenceに追加する場合は、Assets自体またはSub-Assetsを参照することを選択できます。最初に表示されたドロップダウンリストは2つになります。1番目はAssets自体を選択し、2番目はSub-Assetsを選択します。これはメインAssetsへの参照として扱われます。

###5.5ビルドの要件

####5.5.1StreamingAssetsディレクトリのローカルアセット

Addressable Asset Systemは、何をロードするか、どのようにロードするかを知るために、実行時にいくつかのファイルを必要とします。これらのファイルはAddressablesデータを生成し、StreamingAssetフォルダーに保存されます。このフォルダーは、前の章で説明したように、ビルド中のすべてのファイルを含むUnityの特別なフォルダーです。これらのファイルは、Addressableコンテンツが生成されるときにライブラリ内で段階的に処理されます。次に、アプリケーションがビルドされると、システムは必要なファイルをStreamingAssetにコピーし、それらを生成してソースフォルダーから削除します。このようにして、複数のプラットフォームのデータをビルドできますが、同時に、ビルドプラットフォームごとに関連データのコピーを1つだけ含めることができます。
Addressableの特定のデータに加えて、ローカルで使用するデータを作成するグループは、ライブラリプラットフォーム固有のキャッシュの場所も使用します。これが機能することを確認するには、ビルドパスとロードパスをそれぞれ構成ファイル変数として設定する必要があります。つまり、[UnityEngine.AddressableAssets.Addressables.BuildPath]と{UnityEngine.AddressableAssets.Addressables.RuntimePath}から始めます。AddressableAssettingsのInspectorでこれらの設定を指定できます（デフォルトでは、このオブジェクトはプロジェクトのAssets / AddressableAssetsDataディレクトリにあります）。

####5.5.2事前ダウンロード

Addressables.DownloadDependenciesAsync（）メソッドをコールすると、渡されたアドレスまたはラベルの依存関係がロードされます。通常、依存関係はAssetBundleを参照します。
このコールバックによったAsyncOperationHandle構造には、PercentCompleteプロパティが含まれています。それにより、ダウンロードの進行状況を監視や表示することができます。コンテンツのロードが完了するまでアプリケーションを待機させることもできます。
ダウンロードする前にユーザーの同意を取得する場合は、Addressables.GetDownloadSize（）を使用して、特定のアドレスまたはラベルからコンテンツをダウンロードするために必要なスペースを返します。ただし、UnityのAssetBundleキャッシュに残っているため、以前にダウンロードしたBundlesがチェックされることに注意してください。
ほとんどの場合、アプリのAssetを事前にダウンロードしておくと便利ですが、ダウンロードしないことを選択する場合もあります。例えば：
>（1）アプリケーションに多くのオンラインコンテンツがあり、通常、ユーザーがその一部のみを操作するようにしたい場合。
（2）インターネットに接続してから機能できるアプリケーションに対しては、アプリのコンテンツ全体が小さなパッケージの場合は、必要に応じてコンテンツをダウンロードすることを選択できます。

####5.5.3マルチプラットフォームビルド

Addressable Asset Systemは、アプリケーションコンテンツをビルドするときに、Addressable Assetを含むAssetBundlesを生成します。AssetBundleはプラットフォームに依存するため、サポートしたいプラットフォームごとに再構築する必要があります。
デフォルトでは、Addressablesアプリケーションデータをビルドする場合、特定のプラットフォームのデータは、Addressableビルドパスのプラットフォームにある特定のサブディレクトリに格納されます。ランタイムパスは、これらのプラットフォームフォルダーを記述し、該当するアプリケーションデータを指します。
注：Addressables BuildScriptPackedPlayModeスクリプトがEditor Playモードで使用されている場合、Addressableは現在アクティブなビルドターゲットからデータを読み込もうとします。したがって、現在のビルドターゲットデータが現在のエディタープラットフォームと互換性がない場合、問題が発生する可能性があります。

###5.6Addressables systemへのアップグレード

このシステムはとても使いやすいので、既存のプロジェクトをアップグレードできますか？既存のAssetBundlesはどのように処理しますか？方法があります。
####5.6.1直接参照

この方法から移行するには、次の手順に従います。
>（1）オブジェクトへの直接参照をAssetReferencesに置き換えます（たとえば、public GameObjectDirectRefMenger;はpublicAssetReference AssetRefMember;になります）。
（2）Assetsを直接参照のように、適切なコンポーネントのInspectorにドラッグします。
（3）文字列名ではなくオブジェクトに基づいてAssetsをロードする場合は、設定で作成されたAssetReferenceオブジェクトから直接インスタンス化します（例：AssetRefMember.LoadAssetAsync（）;またはAssetRefMember.InstantiateAsync（pos、ROT）;）。注：Addressable Assets systemは、Assetsを非同期でロードします。アセット参照への直接参照を更新する場合は、非同期操作を合わせるためにコードも更新する必要があります。

####5.6.2Resourceフォルダ

Resourcesデータフォルダ内のAssetがAddressableとしてマークされている場合、システムはResourcesフォルダ内のAssetをプロジェクト内のResources_Moveという新しいフォルダに自動的に移動します。Assetsを移動するためのデフォルトのアドレスは、フォルダ名を省略した古いパスです。たとえば、ロードコードがResources.LoadAsync（ “desert / trunk.prefab”）;からAddressables.LoadAssetAsync（ “desert /tank.prefab”）;に変更される場合があります。
####5.6.3AssetBundles

AAddressables Groupウィンドウを開くと、UnityはすべてのAssetBundlesをAddressable Asset Groupsに変換します。これは、コードを移行する最も簡単な方法です。
Assetsを手動で変換する場合は、“Ignore”ボタンをクリックします。次に、前述の直接参照またはResourceフォルダーの方法を使用します。
Assetsアドレスのデフォルトのパスは、そのファイルのパスです。そのパスをAssetsのアドレスとして使用する場合は、パッケージからAssetsをロードするのと同じ方法でAssetsをロードします。Addressable Asset Systemは、パッケージとそのすべての依存関係のロードを処理します。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com