This document describes an approach on how to make the reference's client lightweight by streaming the currently embedded assets.
Every nice UI, sound effect, particle, or material we add to the renderer increases its size. This impacts directly loading times or caching since the client's size will go above the max allowed for it (applied to WebGL, check the PoC for details). The idea is to pack textures, audio files, and other assets and stream them in runtime.
Similar to what we are doing with scene assets, we can pack everything into one or multiple (to always be under the cache size limit) asset packs to be consumed by the client. This solution should be part of a different system than the one used for scene assets. Reasons why we can't reuse the system include, but are not limited to:
The Addressables system provides tools and scripts to organize and package content for an application and an API to load and release assets at runtime. It's an additional abstraction layer over the Asset Bundles System, but it's not limited to this. "Addressables" gives the flexibility to adjust where to host assets and provides mechanisms for dependency resolution, reference counting, simulation, validation, and diagnostics out of the box.
In the first iteration, we are going to use the "Local" mode only:
loader.ts. This will give the necessary URL needed for Unity to complete the corresponding "Web Request".
Currently, the renderer is a self-contained experience; and as for "Local" Addressables, no dedicated versioning is required:
Depending on the specific case, we will use all possible ways to load assets:
- It is desirable to shorten the address and adjust it according to the directories and groups structure. The exact rules of the former will be elaborated on in the production pipeline
Group settings determine how the assets in a group are treated in content builds.
We are going to distribute assets in "Addressable Asset Groups" according to the following rules:
Check Unity guidelines for additional information.
At the moment, we don't have any sensitive data that requires an integrity check. Moreover, for bigger files, it will cause noticeable overhead on loading. So for the groups, we will disable it.
We are going to exclude Scenes and Resources from Addressables Catalog:
"Addressables" uses right the same "Caching" system that "Asset Bundles" does. It works out of the box for all the supported platforms. Even though it is possible to disable caching per group, we will not do it.
We are going to utilize "AssetReference" and "AssetLabelReference" instead of "SerializeField" to properly reference Assets that should be a part of a separate Addressable without creating a strong reference to them.
We can think of several use cases:
Real use cases and distribution of such assets in groups will be refined and defined according to the feature production pipeline with performance in mind.
Currently, we don't have a robust mechanism for cleaning up memory from assets. We are not going to introduce it this time either. Thus, we will keep all the Addressables loaded in memory. Considering it's only the "Local" mode, it's not gonna be a problem.
We will use the "Simulate Groups" mode for loading Addressables in the Editor. It will help us detect and investigate problems earlier. We will prefer it over the "Asset Database" false mode.
Simulate Groups mode (BuildScriptVirtualMode) analyzes content for layout and dependencies without creating asset bundles. Assets load from the asset database through the ResourceManager, as if they were loaded through bundles. To see when bundles load or unload during gameplay, view the asset usage in the Addressables Event Viewer window (Window > Asset Management > Addressables > Event Viewer).
Simulate Groups mode will help us simulate load strategies and tweak our content groups to find the right balance for a production release.
"Addressables" inherits an issue of assets duplication from the Asset Bundles System. Unity thoroughly described the problem and its resolution. "Addressables" provides the "Analyze Tool" and several built-in presets to help detect and/or mitigate such issues.
We have to launch the analysis and fix the issues before pushing Addressables to prevent duplicates and unnecessary implicit references.
On every build iteration, the addressables get rebuilt and dropped in the "Streaming
Assets" folder as per the "Local" configuration. They get built by using the
AddressableAssetSettings.BuildPlayerContent() in the
BuildCommand.cs. After the build process, those addressables files get copied
into a new "Streaming Assets" directory which should be delivered as an artifact
within the same package.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.