Unity Addressable Plugin

AA, full name Addressable, addressable resources, you can split a complete game resources, to achieve the purpose of reducing the installation package and memory usage.

Installation and initialization

  • Install: Windows - > Package Manager, search for Addressable and install.

img

  • 初始化:Window -> Asset Management -> Addressables -> Group

img

After that, there will be an additional folder called AddressableAssetData under the Assets folder

AddressableAssetData目录

img

The AddressableAssetSetting in the root directory saves all the AA basic configurations

AssetGroups directory is the current Group, after initialization, the default is two, BuildInData and DefaultLocalGroup

Below AssetGroups/Schemas are three schemas, the first belongs to the first group and the last two belong to the second group.

Below AssetGroupTemplate is the Template of the Group, which is the template when we create a new Group. By default, there is only one PackdAsset, that is, when we create a new one, we can only choose to create a new one from this template, or create an empty Group.

There are four BuildScripts inside DataBuilders, which are scripts for Build or PlayMode. They need to be configured in the AA basic configuration first (we can also write our own BuildScript, and then add it here for later use), that is

img

Can then be used in PlayMode (first three)

img

And used in Build (fourth)

img

Basic configuration

Profile: Configure the packaged address and Target platform variables

img

img

  • ** Square brackets [ ]**: Addressables evaluates the bracketed entries at build time. These entries can be other configuration file variables (such as [BuildTarget]) or code variables (such as UnityEditor. EditorUserBuildSettings.activeBuildTarget). During build, as it processes your group, Addressables evaluates the bracketed string and writes the results to the directory.

  • ** Curly brackets { }**: Addressables evaluate entries enclosed in braces at runtime. You can use code variables of runtime classes (e.g. {UnityEngine. AddressableAssets. Addressables. RuntimePath})

  • [BuildTarget] can use Unity global variables in square brackets

  • {Addressable. AddressableConfig.server_android_url} can directly reference the Static Variable in the class

  • BuildTarget: Packaged destination platform

  • LocalBuildPath: Path to package local resources

  • LocalLoadPath: The loading path of local resources

  • RemoteBuildPath: The packing path for the remote resource

  • RemoteLoadPath: the loading path of the remote resource

Enable Remote Resource Publishing

Enable Build Remote Catalog, and then set Build & Load Paths to custom, you can select the five variables in the profile mentioned above, where the actual path calculated according to the configuration in the Profile can be displayed.

For example, our current BuildTarget is OSX, so the result of the ServerData/[BuildTarget] calculation of RemoteBuildPath at this time is ServerData/StandaloneOSX

img

It is also possible not to start this. You can still pack Local and Remote resources, and you can also load remote resources. However, if you do not start this, you cannot generate a Catalog with timestamp or version number for Remote resources alone (it would have been in the streamAsset There is a Catalog containing Local and Remote under the folder), so you cannot update the resources separately without updating the App according to the Remote Catalog. For details, please refer to here:Remote content distribution | Addressables | 1.18.16

Creating a New Group

When we create a new Group, we need to create it from a Template. By default, there is a PackedAsset template under AddressableAssetData/AssetGroupTemplates, so we only have one option when creating a new group:

img

New Template

If you create your own build script or utility that requires additional settings, you can define these settings in your own schema object and create your own group template.

  • Use the “Project” panel to navigate to the desired location in the Assets folder.
    Create a blank group template (menu: Assets > Addressables > Group Templates > Blank Group Templates).
  • Give the template an appropriate name.
  • Add instructions in the “Inspector” window if needed.
  • Click the Add Schema button and select from the Schema list.
    Continue adding schemas until all required schemas are added to the list.

If you use the default build script, the group must use a content packaging and loading schema. If you use a content update version, the group must include a content update restriction schema. For more information, see Build.

Add Schema to Template

The built-in schemas include:

  • Content Packing & Loading: this is the main Addressables schema used by the default build script and defines the settings for building and loading Addressable assets.

  • Content Update Restrictions: defines settings for making differential updates of a previous build. See Builds for more information about update builds.

  • Resources and Built In Scenes: a special-purpose schema defining settings for which types of built-in assets to display in the Built In Data group.

These three Schemas are in Library/PackageCache/[email protected]/Editor/Settings/GroupSchemas

img

Creating a Custom Schema

To create your own schema, extend the AddressableAssetGroupSchema class (which is a kind of ScriptableObject).

1
2
3
4
5
6
7
8
9
10
11
using UnityEditor.AddressableAssets.Settings;



public class __CustomSchema __: AddressableAssetGroupSchema

{

public string CustomDescription;

}

Once you have defined your custom schema object, you can add it to existing groups and group templates using the Add Schema buttons found on the Inspector windows of those entities.

Create a new Group for packaging as a remote bundle

If you created a Template in the previous step, you can create a Group directly from the Template. If not, choose to create a Group for Blank, and then add two basic schemas through Add Schema.

img

Then set buildPath and loadPath to remote.

At this time, we can see

img

There are two more schemas, which are the two schemas we just added.

Mark the resource as addressable

Select a resource and check Addressable in Inspector.

img

Resources are placed in the Default Local Group by default

We select two resources to mark as addressable, one to be placed in the default location and one to be moved to our newly created Remote Group.

img

[How to manage AA resources] (https://docs.unity3d.com/Packages/ [email protected]/manual/AddressableAssetsDevelopmentCycle.html)

A few basic principles of reference:Managing Addressables in the Editor | Addressables | 1.18.16

How much volume will AA resources occupy after packaging?

img

If you use the same asset in multiple classes, Unity makes copies of the asset when it builds, rather than sharing a single instance. For example, if you use a Material in a built-in scene, and you also use it in a Prefab located in the Resources folder, you end up with two copies of that Material in your build - even if the Material asset itself is not, located in the Resource. If you subsequently mark the same Material as addressable, you end up with three copies. Files in the Project StreamingAssets folder can never be referenced by assets outside of that folder.

So, try not to use the Resources folder.

Before building the player, you must do a content build on the addressable assets. During the player build, Unity copies your local Addressables to the StreamingAssets folder so that they are included in the build along with any assets you placed in StreamingAssets. (These assets are removed at the end of the build process.) It is your responsibility to upload the remote Addressables files generated by the content build to your hosting service. For more information,

When you add an asset to the Addressables group, the asset is packaged into an AssetBundle when you do a content build. If the asset references other assets (called dependencies), how those dependencies are handled depends on whether they are also addressable. Addressable dependencies are packaged into an AssetBundle depending on the settings of the group they are in - this may be the same package or a different package as the referenced asset. Unaddressable dependencies are contained in the package in which they reference the asset.

If multiple Addressables reference the same non-Addressable asset, copies of the non-Addressable asset are included in each package that contains the reference Addressable.

img

When an asset is implicitly included in multiple packages, a subtle consequence can occur that multiple instances of the asset can be instantiated at runtime, rather than a single instance as expected by your game logic. If you change the instance state at runtime, only objects from the same package can see the change, as all other assets now have their own separate instances instead of sharing public instances.

To eliminate this duplication, you can make the dependency an addressable asset and include it in one of the existing packages or add it to a different package. Once you make the dependency addressable, every time you load one of the addressable objects that reference it, the package to which it belongs will be loaded.

Note that when you reference assets in another package, you must load the package when you load any assets in the current package, not just the assets that contain the reference. Although no assets from other AssetBundles are loaded, loading packages has its own runtime costs

AA How Many Groups Should Resources Split?

Too much danger:

  • Every package has memory overhead. This is related to many of the factors outlined on this page, but in short, this overhead can be significant. If you expect to load 100 or even 1000 packages into memory at a time, this may mean that a large amount of memory is consumed.
  • Downloading packages has a Concurrency Limit. If you need 1000 bundles at the same time, it is not possible to download all bundles at the same time. Some numbers will be downloaded and when they are done, more will be triggered. In practice, this is quite a small problem, so small that you are usually limited by the total size of the download, not how many packages it is divided into.
  • Bundling information can inflate the directory. In order to be able to download or load the directory, we store string-based information about your bundle. Thousands of data packets can greatly increase the size of the directory.
  • Duplicate assets are more likely. Suppose two materials are marked as addressable and each depends on the same texture. If they are in the same package, the texture is pulled in once and referenced by both. If they are in separate packages and the texture itself is not addressable, then it will be copied. Then you need to mark the texture as addressable, accept duplicates, or put the material in the same package.

The dangers of too little binding:

  • UnityWebRequest (which we use to download) will not resume a failed download. So if a large package is being downloaded and your users lose their connection, the download will start again once they regain their connection.

  • Items can be loaded separately from bundles, but not unloaded separately. For example, if you have 10 materials in a bundle, load all 10 and then tell Addressables to release 9 of them, all 10 may be in memory. See Memory Management for more information.

[How to use AA resources at runtime] (https://docs.unity3d.com/Packages/ [email protected]/manual/RuntimeAddressales.html)

Once you organize addressable assets into groups and build them into AssetBundles, you still have to load, instantiate, and finally publish them at runtime.

The first is the behavior of some AA resources in memory, which can help us better manage AA resources and optimize memory usage

[Memory Management] (https://docs.unity3d.com/Packages/ [email protected]/manual/MemoryManagement.html)

The Addressables system manages the memory used to load assets and packages by maintaining a reference count for each project it loads.

When an Addressable is loaded, the system increases the reference count; when the asset is released, the system decreases the reference count. When an Addressable’s reference count goes to zero, it is eligible to be unloaded. When you explicitly load an addressable asset, you must also release the asset when complete.

The basic rule of thumb to avoid “memory leaks” (assets that remain in memory after they are no longer needed) is to mirroring each call to the load function with a call to the release function. You can free the asset using a reference to the asset instance itself or using the result handle returned by the original load operation.

Note, however, that freed assets are not necessarily immediately unloaded from memory. Memory used by an asset is not freed until the AssetBundle to which it belongs is also unloaded. (Freed assets can also be unloaded by callingResources.UnloadUnusedAssets(Uninstall, but this tends to be a slow operation and may cause framerate failures.)

AssetBundles have their own reference counts (the system treats them as addressable objects and treats the assets they contain as dependencies). When you load assets from a package, the package’s reference count increases, and when you free assets, the package’s reference count decreases. When a package’s reference count goes to zero, it means that all the assets it contains are not in use, and the package and all assets it contains are unloaded from memory.

Use事件查看器To monitor your runtime memory management. The viewer shows the time to load and unload assets and their dependencies.

Avoid asset churning

If you release an object that happens to be the last item in the AssetBundle and then immediately reload that asset or other assets in the bundle, you may have an asset churn problem.

For example, suppose you have two materials, boat and plane that share the texture, cammo, that has been pulled into its own AssetBundle. Level 1 boat uses plane and level 2 uses plane. When you exit level 1, you release boat and immediately load plane. When you release boat, Addressables unloads the texture cammo. Then, when you load plane, Addressables immediately reloads cammo.

Memory usage

When you load an AssetBundle, Unity allocates memory to store the package’s internal data, in addition to the memory used for the assets it contains. The main internal data types of the loaded AssetBundle include:

When you organize your Addressable groups and AssetBundles, you usually have to make a trade-off between the size and number of AssetBundles you create and load. On the one hand, fewer, larger packages can minimize the total memory usage of AssetBundles. On the other hand, using a large number of small packages can minimize peak memory usage because you can offload assets and AssetBundles more easily.

Although the size of an AssetBundle on disk differs from its runtime size, you can use the disk size as a rough guide to AssetBundle memory overhead in a build. You can start withBuild Layout ReportGets the package size and other information that can be used to help analyze AssetBundles.

[Load Addressable Assets] (https://docs.unity3d.com/Packages/ [email protected]/manual/LoadingAddressableAssets.html)

TheAddressablesClass provides several ways to load addressable assets. You can load one asset at a time or in batches. To identify the assets to load, you can pass a single key or a list of keys to the load function. A key can be one of the following objects:

  • Address: string containing the address you assign to the asset

  • Label: A string containing labels assigned to one or more assets

  • AssetReference object: instanceAssetReference

  • IResourceLocationInstance: An intermediate object that contains information about loading assets and their dependencies.

When you invoke one of the asset loading functions, the Addressables system begins asynchronous operations for the following tasks:

  1. Find the resource location for the specified key (except the IResourceLocation key)
  2. Collect a list of dependencies
  3. Download any required remote AssetBundles
  4. Load AssetBundles into memory
  5. The operation ofResultObject is set to the loaded object
  6. Of the update operation状态And invoke any CompletedEvent listener

If the load operation is successful, Status will be set to Succeeded and can be accessed fromResultObject accesses the loaded object.

If an error occurs, copy the exception to the action object’sOperationExceptionMember, and set Status to Failed. By default, exceptions are not thrown as part of the operation. However, you canResourceManager.ExceptionHandlerProperty assigns a handler function to handle any exceptions. In addition, you can enableLog Runtime ExceptionsOption to log errors to Unity控制台

When you call a load function that can load multiple addressable assets, you can specify whether the entire operation should abort if any single load operation fails, or whether the operation should load any assets that can be loaded. In both cases, the operation state is set to failed. (‘releaseDependenciesOnFailure’ sets the parameter to true when calling the load function to abort the entire operation on any failure.)

Try to build full package

To build your content artifacts:

  1. Configure your group settings.
  2. If you want to distribute content remotely, configure your profile and addressable system settings to enable remote information delivery.
  3. Select the correct configuration file.
  4. FromGroups 窗口Start building.

Since we did not create a custom Profile, we temporarily use the default Profile for packaging testing

Default configured path

Default local path

The local build path defaults toAddressables.BuildPathThe provided path, which is located in the Library folder of the Unity project. Addressables appends the folder to the local build path based on your current platform build target settings. When you build for multiple platforms, the build puts artifacts for each platform in different subfolders.

Similarly, the local loading path defaults toAddressables.RuntimePathThe provided path, resolved to the StreamingAssets folder. Addressables again adds the platform build target to the path.

When you build a local package to the default build path, the build code temporarily copies artifacts from the build path to the StreamingAssets folder when you build the player (and deletes them after the build).

If you build to or load from a custom local path, it is your responsibility to copy the build artifacts to the correct location in the project before proceeding with the player build, and to ensure that your application can access these artifacts at runtime.

Default remote path

Addressables sets the default remote build path to an arbitrarily selected folder name “ServerData” created under your project folder. The build adds the current platform target as a subfolder to the path to separate unique artifacts for different platforms.

The default remote load path is “http://localhost/” with the current configuration file BuildTarget variable attached. You must change this path to the base URL where you plan to load the addressable asset.

Depending on the type of development, testing, or release you are doing, use different profiles to set the remote load path. For example, you could have a profile to load assets from localhost server for general development builds, a profile to load assets from a staging environment for QA builds, and a profile to load assets from your content delivery network (CDN) for release builds

Packaging results

Local packing result

img

img

You can see that the content is split into two bundles. The reason is that there is a scene in the locally packaged resources. This group containing the scene will split into one more bundle.

Remote content packing result

img

Packaged product analysis

Locally packaged products

Because we currently only package resources for OS, there is only OSX under the aa folder.

By default, the build creates files in your configuration file settings for the locations defined by the LocalBuildPath and RemoteBuildPath variables. The files Unity uses for your player build include AssetBundles (.bundle), directory JSON and hash files, and settings files.

In most cases, you should not change the local build or load path from the default. If you do, you must copy the local build artifact from the custom build location to the StreamingAssets folder of your project before you do the Player build. Changing these paths will also prevent you from having Addressable as part of the Player Build

If we select the resource as RemoteBuildPath, then we need to manually upload the resource to the CDN.

The content build also creates the following files, which are not directly used in the Player build

  • addressables_content_state.bin: used to make a content update build. If you support dynamic content updates, you must save this file after each content release. Otherwise, you can ignore this file.

  • AddressablesBuildTEP.json: logs build performance data. See Build Profiling.

See Building Addressable content for more information about how to set up and perform a content build.

Remote resource packaging product

The remotely packaged product will also have an additional hash to verify the correctness of the downloaded resource.

But its bin file is in the Asset directory.

The name of the product will also have an additional timestamp to avoid untimely updates due to caching.

img

If the above configuration is enabled, the product name is not timestamp but version number.

Try incremental updates

Local bundles do not need this, because all the file contents are packaged in the Application.

When you distribute content remotely, you can perform differential updates on previously released builds to minimize the amount of data users have to download (compared to full builds).

Once the remote group is properly configured and you have a previous build that contains the remote content, you can perform a content update build in the following ways:

In addition to opening Build

One is Content.

The other is unique.

  1. Run the Check for Content Update Restrictions tool.

This step may show that there are no changes, because it does not detect the Static Group, because only Static needs to create a Content.

Important: Before you run the Check for Content Update Restrictions tool, you should make a branch with your version control system. The tool rearranges your asset groups in a way suited for updating content. Branching ensures that next time you ship a full player build, you can return to your preferred content arrangement.

Step 1 OpenGroups 窗口 (菜单:Windows > Asset Management > Addressables > Groups)。
2. Select the desired configuration file from the Profile menu on the toolbar.
3. Select Update a Previous Build from the Build menu. The File Picker dialog box opens.

img

  1. Locate the addressables_content_state generated by the build you are updating. (The default location is in your Assets/AddressableAssetsData/TargetPlatform folder.)
  2. Click Open to start the update build.

This build method requires the bin file generated by the last full build, that is, the bin file will only be generated and modified during the full build, and the Previous Build in Update a Previous Build refers to always the last full build, even if you have done other incremental builds in between.

Full build runs every time you update the entire Application, and if you only want to update AA resources without republishing the App, you only need to select Build Remote Catalog during full build, which will build a catalog for Remote resources separately. Each time you pull the Remote resource, it will automatically detect whether the remote has a new version of the resource

You must save the addressables_content_state.bin file produced by the Default Build Script for each build that you intend to update in the future. This file is updated every time you run the build script. Be sure to save the version produced for the content build that you publish.

Local environment construction

New Editor

When we use Remote resources, the default LoadPath does not actually start the service. In order to simulate this situation locally, AA provides Editor Host.

img

Creating a new host

img

After selecting enable, a server will be started

img

At this time the service started, we successfully hosted the bundle on the local port 8888, but the problem now is that the RemoteBuildPath in our Profile is still http://localhost/ [BuildTarget], if we use variables, we will not be able to load correctly, so we need to Create a new Profile and modify its 8888 port based on RemoteLoadPath.

New Editor

When using managed services during development, please consider creating a configuration file that configures asset groups to be loaded from managed services. For more information about configuration files, please refer to可寻址资产配置文件

Once you have entered the Addressables Profiles window, create a new profile via Create ** > ** Profile. In the following example, the new profile is called “Editor Hosted”.

Modify the remote load URL to load from the hosting service. In the Addressables Hosting window, you can construct the path URL (for example,) using the fields named [PrivateIpAddress] and in the remote LoadPath variable. http://[PrivateIpAddress]: [HostingServicePort]/[BuildTarget]

img

  • Configure the configuration file of the service. *

Verify that each group is configured correctly. Make sure you placeBuildPathAndLoadPathThe path is set to the respective profile key that you modify for the managed service. In this example, you can see how it should be extendedLoadPath 中Configuration file variables to build the correct base URL for loading assets from the hosting service.

img

Then switch the currently active profile to Editor Hosted.

Modify Play

img

  • Use the Asset database: Addressables loads Assets directly from the Asset database. This option typically provides the fastest iteration speed if you are making both code and Asset changes, but also least resembles a production build.

  • Simulate groups: Addressables loads Assets while simulating groups. This option is helpful if you are working on organizing and optimizing your Addressables groups themselves. It provides Addressables events without requiring a full content rebuild after every change.

  • Use existing build: Addressables loads content from your last content build. This option most resembles a production build and can provide fast iteration turnaround if you aren’t changing Assets.

New production environment configuration

For the production environment, we also need to create a Profile

img

Don’t forget to upload the content under BuildPath to LoadPath

CI/CD build

Scripts required for packaging:AddressableAssetSettings.BuildPlayerContent | Addressables | 1.15.1

The reason why I use the 1.15 version of the doc is because the 1.18 doc does not introduce the use of API changes

Advanced Tutorial

Other configuration:Addressable Asset Settings | Addressables | 1.18.16

Resource management:Managing Addressables in the Editor | Addressables | 1.18.16

Resource packaging:Building content | Addressables | 1.18.16

Remote resource distribution:Remote content distribution | Addressables | 1.18.16

Analysis tools:Diagnostic tools | Addressables | 1.18.16

Resource preload:Preloading dependencies | Addressables | 1.18.16,[AssetBundle Loading | Addressables | 1.18.16](