Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [1.17.5-preview] - 2021-02-08
- Fixed performance issue when disabling "Addressable" for multiple Assets in the Inspector.
- Added option to set the build path of addressables_content_state.bin file.
- The buildlogtep.json file is not generated when building the catalog bundle.
- Fixed invalid handle exception getting thrown when static AssetReferences were used with domain reload turned off
- Fixed catalog using invalid load path for Groups built with "bundle naming mode" "Filename".
- Added option to set custom prefix on the unitybuiltinshader AssetBundle
- Added documentation explaining how dependencies affect Content Update
- Sub-assets with arbitrary main type can now be assigned to an asset reference if types match
  • Loading branch information
Unity Technologies committed Feb 8, 2021
1 parent 579a538 commit 9d20348
Show file tree
Hide file tree
Showing 24 changed files with 550 additions and 118 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.17.5-preview] - 2021-02-08
- Fixed performance issue when disabling "Addressable" for multiple Assets in the Inspector.
- Added option to set the build path of addressables_content_state.bin file.
- The buildlogtep.json file is not generated when building the catalog bundle.
- Fixed invalid handle exception getting thrown when static AssetReferences were used with domain reload turned off
- Fixed catalog using invalid load path for Groups built with "bundle naming mode" "Filename".
- Added option to set custom prefix on the unitybuiltinshader AssetBundle
- Added documentation explaining how dependencies affect Content Update
- Sub-assets with arbitrary main type can now be assigned to an asset reference if types match

## [1.17.4-preview] - 2021-01-27
- Removed unnecessary logging when deleting temporary Addressables build data.
- Added WaitForCompletion() on AsyncOperationHandles. This allows async operation to be executed synchronously
Expand Down Expand Up @@ -62,6 +72,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- The "Ignore Invalid/Unsupported Files" option is now saved in the settings
- Fixed issue where Filename only bundle naming schemas were overwriting old bundles prematurely in content update.

## [1.16.16] - 2021-01-20
- Updated dependency versions for testcase fix

## [1.16.15] - 2020-12-09
- Addressables link.xml should now have it's own folder.
- Fixed an issue where InvalidKeyException was getting thrown when calling GetDownloadSizeAsync on scenes
Expand Down
13 changes: 11 additions & 2 deletions Documentation~/AddressableAssetsAsyncOperationHandle.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
uid: addressables-async-operation-handling
---
# Async operation handling
Several methods from the [`Addressables`](xref:UnityEngine.AddressableAssets.Addressables) API return an [`AsyncOperationHandle`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle) struct. The main purpose of this handle is to allow access to the status and result of an operation. The result of the operation is valid until you call [`Addressables.Release`](xref:UnityEngine.AddressableAssets.Addressables.Release(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle)) or [`Addressables.ReleaseInstance`](xref:UnityEngine.AddressableAssets.Addressables.ReleaseInstance(UnityEngine.GameObject)) with the operation (for more information on releasing assets, see documentation on [memory management](MemoryManagement.md).
Several methods from the [`Addressables`](xref:UnityEngine.AddressableAssets.Addressables) API return an [`AsyncOperationHandle`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle) struct. The main purpose of this handle is to allow access to the status and result of an operation. The result of the operation is valid until you call [`Addressables.Release`](xref:UnityEngine.AddressableAssets.Addressables.Release(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle)) or [`Addressables.ReleaseInstance`](xref:UnityEngine.AddressableAssets.Addressables.ReleaseInstance(UnityEngine.GameObject)) with the operation (for more information on releasing assets, see documentation on [memory management](MemoryManagement.md)).

When the operation completes, the [`AsyncOperationHandle.Status`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle) property is either [`AsyncOperationStatus.Succeeded`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus) or [`AsyncOperationStatus.Failed`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus). If successful, you can access the result through the `AsyncOperationHandle.Result` property.

Expand All @@ -26,6 +26,15 @@ AsyncOperationHandle<Texture2D> textureHandle2 = nonGenericHandle.Convert<Textur
AsyncOperationHandle<Texture> textureHandle3 = nonGenericHandle.Convert<Texture>();
```

### PercentComplete vs. GetDownloadStatus
AsyncOperationHandle has two methods that can reflect the progress of the operation.
[`GetDownloadStatus()`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.GetDownloadStatus) will return a `DownloadStatus` struct. This contains information about how many bytes have been downloaded, and how many are needed. The DownloadStatus.Percent is a helper method that represents the percentage of bytes downloaded.
[`PercentComplete`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.PercentComplete) on the other hand, will return an equally-weighted aggregate percentage of all sub-operations. This percent complete is useful to get a sense of progress, but it may not accurately reflect what you would expect depending on the makeup of your operations.

One example would be a call to `Addressables.DownloadDependenciesAsync`, where 5 asset bundles needed downloading. Here `GetDownloadStatus()` would inform you of the progress towards to total number of bytes needed, while `PercentComplete` would have each of the 5 downloads representing 20% of the total, regardless of their size.

In another example, `LoadAssetAsync()` is called, and one bundle needs downloading before an asset can be loaded from it. Here, the download could represent 50% of `PercentComplete`, and the actual load into memory could represent the other 50%. In this instance, `GetDownloadStatus()` would represent the download need, and would reach 100% before the operation finished, as the operation had more to do after downloading.

### AsyncOperationHandle use case examples
Register a listener for completion events using the [`AsyncOperationHandle.Completed`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed) callback:

Expand Down Expand Up @@ -81,7 +90,7 @@ When loading an Addressable Scene, all the dependencies for your GameObjects in

Note: If you mark a GameObject in an Addressable loaded scene as `DontDestroyOnLoad` or move it to another loaded Scene and then unload your original Scene, all dependencies for your GameObject are still unloaded.

If you find yourself in that scenario there are a couple options at your disposal.
If you find yourself in that scenario there are a couple options at your disposal:
- Make the GameObject you want to be `DontDestroyOnLoad` a single Addressable prefab. Instantiate the prefab when you need it and then mark it as `DontDestroyOnLoad`.
- Before unloading the Scene that contained the GameObject you mark as `DontDestroyOnLoad`, call `Addressables.ResourceManager.Acquire(AsyncOperationHandle)` and pass in the Scene load handle. This increases the reference count on the Scene, and keeps it and its dependencies loaded until `Release` is called on the acquired handle.

2 changes: 1 addition & 1 deletion Documentation~/AddressableAssetsCustomOperation.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ The [`ResourceManager`](xref:UnityEngine.ResourceManagement.ResourceManager) inv
When your custom operation completes, call [`AsyncOperationBase.Complete`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1.Complete(`0,System.Boolean,System.String)) on your custom operation object. You can call this within the [`Execute`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1.Execute) method or defer it to outside the call. Calling `AsyncOperationBase.Complete` notifies the [`ResourceManager`](xref:UnityEngine.ResourceManagement.ResourceManager) that the operation is complete and will invoke the associated [`AsyncOperationHandle.Completed`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.Completed) events.

#### Terminating the operation
The [`ResourceManager`](xref:UnityEngine.ResourceManagement.ResourceManager) invokes [`AsyncOperationBase.Destroy`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1.Destroy) method for your custom operation when you release the [`AsyncOperationHandle`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle) that references it. This is where you should release any memory or resources associated with your custom operation.
The [`ResourceManager`](xref:UnityEngine.ResourceManagement.ResourceManager) invokes the [`AsyncOperationBase.Destroy`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1.Destroy) method for your custom operation when you release the [`AsyncOperationHandle`](xref:UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle) that references it. This is where you should release any memory or resources associated with your custom operation.
1 change: 1 addition & 0 deletions Documentation~/AddressableAssetsMigrationGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ To migrate from this approach, follow these steps:
1. Replace your direct references to objects with asset references (for example, `public GameObject directRefMember;` becomes `public AssetReference AssetRefMember;`).
2. Drag assets onto the appropriate component’s Inspector, as you would for a direct reference.
3. If you'd like to load an asset based on an object rather than a string name, instantiate it directly from the [`AssetReference`](xref:UnityEngine.AddressableAssets.AssetReference) object you created in your setup (for example, `AssetRefMember.LoadAssetAsync<GameObject>();` or `AssetRefMember.InstantiateAsync(pos, rot);`).
4. When the Asset is not needed anymore, it must be unloaded with the [`Addressables.Release`](xref:UnityEngine.AddressableAssets.Addressables.Release``1(``0)) method. See [Mirroring load and unload](MemoryManagement.md#mirroring-load-and-unload) for details.

**Note**: The Addressable Asset system loads assets asynchronously. When you update your direct references to asset references, you must also update your code to operate asynchronously.

Expand Down
12 changes: 6 additions & 6 deletions Documentation~/AddressablesFAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Dangers of too many bundles:
* Greater likelihood of duplicated assets. Say two materials are marked as Addressable and each depend on the same texture. If they are in the same bundle, then the texture is pulled in once, and referenced by both. If they are in separate bundles, and the texture is not itself Addressable, then it will be duplicated. You then either need to mark the texture as Addressable, accept the duplication, or put the materials in the same bundle.

Dangers of too few bundles:
* The UnityWebRequest (which we use to download) does not resume failed downloads. So if a large bundle downloading and your user loses connection, the download is started over once they regain connection.
* The UnityWebRequest (which we use to download) does not resume failed downloads. So if a large bundle is downloading and your user loses connection, the download is started over once they regain connection.
* Items can be loaded individually from bundles, but cannot be unloaded individually. For example, if you have 10 materials in a bundle, load all 10, then tell Addressables to release 9 of them, all 10 will likely be in memory. This is also covered [on the memory management page](MemoryManagement.md#when-is-memory-cleared).

### What compression settings are best?
Expand All @@ -34,19 +34,19 @@ More information on Unity's compression selection is available in the [Asset Bun
### Are there ways to miminize the catalog size?
Currently there are two optimizations available.
1. Compress the local catalog. If your primary concern is how big the catalog is in your build, there is an option in the inspector for the top level settings of **Compress Local Catalog**. This option builds catalog that ships with your game into an asset bundle. Compressing the catalog makes the file itself smaller, but note that this does increase catalog load time.
2. Disable built-in scenes and Resources. Addressables provides the ability to load content from Resources and from the built-in scenes list. By default this feature is on, which can bloat the catalog if you do not need this feature. To disable it, select the "Built In Data" group within the Groups window (**Window** > **Asset Management** > **Addressables** > **Groups**). From the settings for that group, you can uncheck "Include Resources Folders" and "Include Build Settings Scenes". Unchecking these option only removes the references to those asset types from the Addressables catalog. The content itself is still built into the player you create, and you can still load them via legacy API.
2. Disable built-in scenes and Resources. Addressables provides the ability to load content from Resources and from the built-in scenes list. By default this feature is on, which can bloat the catalog if you do not need this feature. To disable it, select the "Built In Data" group within the Groups window (**Window** > **Asset Management** > **Addressables** > **Groups**). From the settings for that group, you can uncheck "Include Resources Folders" and "Include Build Settings Scenes". Unchecking these options only removes the references to those asset types from the Addressables catalog. The content itself is still built into the player you create, and you can still load it via legacy API.

### What is addressables_content_state?
After every content build of Addressables, we produce an addressables_content_state.bin file, which is saved to the `Assets/AddressableAssetsData/<Platform>/` folder of your Unity project.
After every content build of Addressables, we produce an addressables_content_state.bin file, which is saved to the folder path defined in the Addressable Assets Settings value "Content State build Path" appended with /<Platform>. If this value is empty, the default location will be the `Assets/AddressableAssetsData/<Platform>/` folder of your Unity project.
This file is critical to our [content update workflow](ContentUpdateWorkflow.md). If you are not doing any content updates, you can completely ignore this file.
If you are planning to do content updates, you will need the version of this file produced for the previous release. We recommend checking it into version control and creating a branch each time you release a player build. More information is available on our [content update workflow page](ContentUpdateWorkflow.md).

### What are possible scale implications?
As your project grows larger, keep an eye on the following aspects of your assets and bundles:
* Total bundle size - Historically Unity has not supported files larger than 4GB. This has been fixed in some recent editor versions, but there can still be issues. It is recommended to keep the content of a given bundle under this limit for best compatibility across all platforms.
* Sub assets affecting UI performance. There is no hard limit here, but if you have many assets, and those assets have many sub-assets, it may be best to turn off sub-asset display. This option only affects how the data is displayed in the Groups window, and does not affect what you can and cannot load at runtime. The option is available in the groups window under **Tools** > **Show Sprite and Subobject Addresses**. Disabling this will make the UI more responsive.
* Group hierarchy display. Another UI-only option to help with scale is **Group Hierarchy with Dashes**. This is available within the inspector of the top level settings. With this enabled, groups that contain dashes '-' in their names will display as if the dashes represented folder hierarchy. This does not affect the actual group name, or the way things are built. For example, two groups called "x-y-z" and "x-y-w" would display as if inside a folder called "x", there was a folder called "y". Inside that folder were two groups, called "x-y-z" and "x-y-w". This will not really affect UI responsiveness, but simply makes it easier to browse a large collection of groups.
* Bundle layout at scale. For more information about how best to set up your layout, see the earlier question: [_Is it better to have many small bundles or a few bigger ones_](AddressablesFAQ.md#Is-it-better-t-have-many-small-bundles-or-a-few-bigger-ones)
* Sub assets affecting UI performance - There is no hard limit here, but if you have many assets, and those assets have many sub-assets, it may be best to turn off sub-asset display. This option only affects how the data is displayed in the Groups window, and does not affect what you can and cannot load at runtime. The option is available in the groups window under **Tools** > **Show Sprite and Subobject Addresses**. Disabling this will make the UI more responsive.
* Group hierarchy display - Another UI-only option to help with scale is **Group Hierarchy with Dashes**. This is available within the inspector of the top level settings. With this enabled, groups that contain dashes '-' in their names will display as if the dashes represented folder hierarchy. This does not affect the actual group name, or the way things are built. For example, two groups called "x-y-z" and "x-y-w" would display as if inside a folder called "x", there was a folder called "y". Inside that folder were two groups, called "x-y-z" and "x-y-w". This will not really affect UI responsiveness, but simply makes it easier to browse a large collection of groups.
* Bundle layout at scale - For more information about how best to set up your layout, see the earlier question: [_Is it better to have many small bundles or a few bigger ones_](AddressablesFAQ.md#Is-it-better-t-have-many-small-bundles-or-a-few-bigger-ones)

### Is it possible to retrieve the address of an asset or reference at runtime?
In the most general case, loaded assets no longer have a tie to their address or `IResourceLocation`. There are ways, however, to get the properly associated `IResourceLocation` and use that to read the field PrimaryKey. The PrimaryKey field will be set to the assets's address unless "Include Address In Catalog" is disabled for the group this object came from. In that case, the PrimaryKey will be the next item in the list of keys (probably a GUID, but possibly a Label or empty string).
Expand Down
Loading

0 comments on commit 9d20348

Please sign in to comment.