### Instantiate and release an AssetReference as a child of the current GameObject Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/asset-reference-create.html Use this MonoBehaviour to instantiate an AssetReference as a child of the current GameObject in Start and release it in OnDestroy. The reference is checked for null and validity before use. This example uses the AssetReferenceGameObject type. ```csharp using UnityEngine; using UnityEngine.AddressableAssets; internal class InstantiateReference : MonoBehaviour { [SerializeField] private AssetReferenceGameObject reference; void Start() { if (reference != null) reference.InstantiateAsync(this.transform); } private void OnDestroy() { if (reference != null && reference.IsValid()) reference.ReleaseAsset(); } } ``` -------------------------------- ### Load prefab synchronously with WaitForCompletion Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/SynchronousAddressables.html Example of loading a prefab synchronously by address with Addressables.LoadAssetAsync and waiting for completion via WaitForCompletion(). Releases the handle on failure or when the GameObject is destroyed. ```csharp using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; internal class LoadSynchronously : MonoBehaviour { public string address; AsyncOperationHandle opHandle; void Start() { opHandle = Addressables.LoadAssetAsync(address); opHandle.WaitForCompletion(); // Returns when operation is complete if (opHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(opHandle.Result, transform); } else { opHandle.Release(); } } void OnDestroy() { opHandle.Release(); } } ``` -------------------------------- ### Addressables.LoadSceneAsync Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/LoadingScenes.html Documentation for the Addressables.LoadSceneAsync method, including parameters, return type, and a code example. ```APIDOC ## Addressables.LoadSceneAsync ### Description Loads an Addressable scene asset by address or other key object. Uses `SceneManager.LoadSceneAsync` internally and supports the same parameters. ### Method `Addressables.LoadSceneAsync` ### Parameters - **key** (object) - Required - The key of the scene asset to load (e.g., address string). - **loadMode** (LoadSceneMode) - Optional - Whether to add the loaded scene to the current scene or unload and replace it. Defaults to `LoadSceneMode.Single`. - **loadSceneParameters** (LoadSceneParameters) - Optional - Includes `loadMode` and `localPhysicsMode` to specify whether to create a 2D or 3D physics scene. - **activateOnLoad** (bool) - Optional - Whether to activate the scene as soon as it finishes loading or wait until `SceneInstance.ActivateAsync` is called. Defaults to `true`. - **priority** (int) - Optional - The priority of the `AsyncOperation` used to load the scene. Defaults to `100`. ### Returns `AsyncOperationHandle` - A handle to the scene loading operation. ### Example ```csharp using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; internal class LoadSceneByAddress : MonoBehaviour { public string key; // address string private AsyncOperationHandle loadHandle; void Start() { loadHandle = Addressables.LoadSceneAsync(key, LoadSceneMode.Additive); } void OnDestroy() { Addressables.UnloadSceneAsync(loadHandle); } } ``` ``` -------------------------------- ### Load assets with async/await and Task Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/load-wait-asynchronous-async-await.html Loads Addressable assets by a list of keys using async/await. The method signature must include async and await with the operation handle's Task property. The Start method suspends until the task finishes, then instantiates all loaded prefabs in a grid pattern. Release the handle in OnDestroy. ```csharp using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; internal class LoadWithTask : MonoBehaviour { // Label or address strings to load public List keys = new List() {"characters", "animals"}; // Operation handle used to load and release assets AsyncOperationHandle> loadHandle; public async void Start() { loadHandle = Addressables.LoadAssetsAsync( keys, // Either a single key or a List of keys addressable => { // Called for every loaded asset Debug.Log(addressable.name); }, Addressables.MergeMode.Union, // How to combine multiple labels false); // Whether to fail if any asset fails to load // Wait for the operation to finish in the background await loadHandle.Task; // Instantiate the results float x = 0, z = 0; foreach (var addressable in loadHandle.Result) { if (addressable != null) { Instantiate(addressable, new Vector3(x++ * 2.0f, 0, z * 2.0f), Quaternion.identity, transform); // make child of this object if (x > 9) { x = 0; z++; } } } } private void OnDestroy() { loadHandle.Release(); // Release all the loaded assets associated with loadHandle // Note that if you do not make loaded addressables a child of this object, // then you will need to devise another way of releasing the handle when // all the individual addressables are destroyed. } } ``` -------------------------------- ### Run a web server for remote content with npx http-server Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/profiles-default-paths.html Use this command to host remote content locally. It starts a web server on port 8080 with caching disabled (-c-1) and binds to all interfaces (-a 0.0.0.0). ```bash npx http-server -a 0.0.0.0 -p 8080 -c-1 ``` -------------------------------- ### Add CCD build hooks with CcdBuildEvents.PrependPreBuildEvent and PrependPreUpdateEvent Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/ccd-publish.html Adds custom build hooks to the CCD pre-build and pre-update event chains. The example registers a method that logs the current CCD environment, bucket, and badge. Requires the ENABLE_CCD scripting define symbol and the UnityEditor.AddressableAssets.Build namespace. ```csharp #if (UNITY_EDITOR && ENABLE_CCD) using System.Threading.Tasks; using UnityEditor.AddressableAssets.Build; public class BuildHooks { static void AddBuildHook() { CcdBuildEvents.PrependPreBuildEvent(PrintBucketInformation); CcdBuildEvents.PrependPreUpdateEvent(PrintBucketInformation); } static async Task PrintBucketInformation(AddressablesDataBuilderInput input) { UnityEngine.Debug.Log($"Environment: {CcdManager.EnvironmentName}"); UnityEngine.Debug.Log($"Bucket: {CcdManager.BucketId}"); UnityEngine.Debug.Log($"Badge: {CcdManager.Badge}"); return true; } } #endif ``` -------------------------------- ### BuildLauncher menu commands for Addressables and Player builds Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/build-scripting-start-build.html Adds two Editor menu commands under Window > Asset Management > Addressables: one builds Addressables content only, the other builds content and then the Player if content succeeds. Uses preset profile and build script paths. If the build script makes changes requiring a domain reload, run it via command line instead of interactively. ```csharp #if UNITY_EDITOR using UnityEditor; using UnityEditor.AddressableAssets.Build; using UnityEditor.AddressableAssets.Settings; using System; using UnityEngine; internal class BuildLauncher { public static string build_script = "Assets/AddressableAssetsData/DataBuilders/BuildScriptPackedMode.asset"; public static string settings_asset = "Assets/AddressableAssetsData/AddressableAssetSettings.asset"; public static string profile_name = "Default"; private static AddressableAssetSettings settings; static void getSettingsObject(string settingsAsset) { // This step is optional, you can also use the default settings: //settings = AddressableAssetSettingsDefaultObject.Settings; settings = AssetDatabase.LoadAssetAtPath(settingsAsset) as AddressableAssetSettings; if (settings == null) Debug.LogError($"{settingsAsset} couldn't be found or isn't " + $"a settings object."); } static void setProfile(string profile) { string profileId = settings.profileSettings.GetProfileId(profile); if (String.IsNullOrEmpty(profileId)) Debug.LogWarning($"Couldn't find a profile named, {profile}, " + $"using current profile instead."); else settings.activeProfileId = profileId; } static void setBuilder(IDataBuilder builder) { int index = settings.DataBuilders.IndexOf((ScriptableObject)builder); if (index > 0) settings.ActivePlayerDataBuilderIndex = index; else Debug.LogWarning($"{builder} must be added to the " + $"DataBuilders list before it can be made " + $"active. Using last run builder instead."); } static bool buildAddressableContent() { AddressableAssetSettings .BuildPlayerContent(out AddressablesPlayerBuildResult result); bool success = string.IsNullOrEmpty(result.Error); if (!success) { Debug.LogError("Addressables build error encountered: " + result.Error); } return success; } [MenuItem("Window/Asset Management/Addressables/Build Addressables only")] public static bool BuildAddressables() { getSettingsObject(settings_asset); setProfile(profile_name); IDataBuilder builderScript = AssetDatabase.LoadAssetAtPath(build_script) as IDataBuilder; if (builderScript == null) { Debug.LogError(build_script + " couldn't be found or isn't a build script."); return false; } setBuilder(builderScript); return buildAddressableContent(); } [MenuItem("Window/Asset Management/Addressables/Build Addressables and Player")] public static void BuildAddressablesAndPlayer() { bool contentBuildSucceeded = BuildAddressables(); if (contentBuildSucceeded) { var options = new BuildPlayerOptions(); BuildPlayerOptions playerSettings = BuildPlayerWindow.DefaultBuildMethods.GetBuildPlayerOptions(options); BuildPipeline.BuildPlayer(playerSettings); } } } #endif ``` -------------------------------- ### Transform InternalId with Addressables.InternalIdTransformFunc Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/TransformInternalId.html Assign a custom method to Addressables.InternalIdTransformFunc to append a query string to all AssetBundle URLs that start with "http". The method must be set before the relevant operation starts; setting it to null reverts to default behavior. ```csharp using UnityEngine.ResourceManagement.ResourceLocations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.AddressableAssets; static class IDTransformer { //Implement a method to transform the internal ids of locations static string MyCustomTransform(IResourceLocation location) { if (location.ResourceType == typeof(IAssetBundleResource) && location.InternalId.StartsWith("http", System.StringComparison.Ordinal)) return location.InternalId + "?customQueryTag=customQueryValue"; return location.InternalId; } //Override the Addressables transform method with your custom method. //This can be set to null to revert to default behavior. [RuntimeInitializeOnLoadMethod] static void SetInternalIdTransform() { Addressables.InternalIdTransformFunc = MyCustomTransform; } } ``` -------------------------------- ### BatchBuild class for command-line Addressables and player builds Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/build-scripting-recompiling.html Defines a BatchBuild class with two static methods for command-line use. ChangeSettings reads the -defines= argument and sets scripting define symbols for the current build target group. BuildContentAndPlayer sets the Addressables profile and data builder, builds Addressables content, then builds the player, throwing exceptions on errors. ```csharp #if UNITY_EDITOR using System; using UnityEditor; using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Build; using UnityEditor.AddressableAssets.Settings; using UnityEditor.Build.Reporting; using UnityEngine; internal class BatchBuild { public static string build_script = "Assets/AddressableAssetsData/DataBuilders/BuildScriptPackedMode.asset"; public static string profile_name = "Default"; public static void ChangeSettings() { string defines = ""; string[] args = Environment.GetCommandLineArgs(); foreach (var arg in args) if (arg.StartsWith("-defines=", System.StringComparison.CurrentCulture)) defines = arg.Substring(("-defines=".Length)); var buildSettings = EditorUserBuildSettings.selectedBuildTargetGroup; var namedBuildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(buildSettings); PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, defines); } public static void BuildContentAndPlayer() { AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings; settings.activeProfileId = settings.profileSettings.GetProfileId(profile_name); IDataBuilder builder = AssetDatabase.LoadAssetAtPath(build_script) as IDataBuilder; settings.ActivePlayerDataBuilderIndex = settings.DataBuilders.IndexOf((ScriptableObject)builder); AddressableAssetSettings.BuildPlayerContent(out AddressablesPlayerBuildResult result); if (!string.IsNullOrEmpty(result.Error)) throw new Exception(result.Error); BuildReport buildReport = BuildPipeline.BuildPlayer(EditorBuildSettings.scenes, "d:/build/winApp.exe", EditorUserBuildSettings.activeBuildTarget, BuildOptions.None); if (buildReport.summary.result != BuildResult.Succeeded) throw new Exception(buildReport.summary.ToString()); } } #endif ``` -------------------------------- ### Override UnityWebRequest URL with Addressables.WebRequestOverride Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/TransformInternalId.html Assign a method to Addressables.WebRequestOverride in Start to modify the UnityWebRequest before it is sent. The method appends a query string to URLs ending in .bundle, .json, or .hash. Must be assigned before the download operation starts; otherwise Unity uses the default UnityWebRequest. ```csharp using UnityEngine; using UnityEngine.Networking; using UnityEngine.AddressableAssets; internal class WebRequestOverride : MonoBehaviour { //Register to override WebRequests Addressables creates to download private void Start() { Addressables.WebRequestOverride = EditWebRequestURL; } //Override the url of the WebRequest, the request passed to the method is what would be used as standard by Addressables. private void EditWebRequestURL(UnityWebRequest request) { if (request.url.EndsWith(".bundle", StringComparison.OrdinalIgnoreCase)) request.url = request.url + "?customQueryTag=customQueryValue"; else if (request.url.EndsWith(".json", StringComparison.OrdinalIgnoreCase) || request.url.EndsWith(".hash", StringComparison.OrdinalIgnoreCase)) request.url = request.url + "?customQueryTag=customQueryValue"; } } ``` -------------------------------- ### Monitor download progress with GetDownloadStatus Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/remote-content-predownload.html Use GetDownloadStatus().Percent to monitor download progress and dispatch progress/completion events. The loop reports progress at most every 10% and releases the handle after completion. ```csharp using System.Collections; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; internal class PreloadWithProgress : MonoBehaviour { public string preloadLabel = "preload"; public UnityEvent ProgressEvent; public UnityEvent CompletionEvent; private AsyncOperationHandle downloadHandle; IEnumerator Start() { downloadHandle = Addressables.DownloadDependenciesAsync(preloadLabel, false); float progress = 0; while (downloadHandle.Status == AsyncOperationStatus.None) { float percentageComplete = downloadHandle.GetDownloadStatus().Percent; if (percentageComplete > progress * 1.1) // Report at most every 10% or so { progress = percentageComplete; // More accurate % ProgressEvent.Invoke(progress); } yield return null; } CompletionEvent.Invoke(downloadHandle.Status == AsyncOperationStatus.Succeeded); downloadHandle.Release(); //Release the operation handle } } ``` -------------------------------- ### Check and update specific catalogs with Addressables.CheckForCatalogUpdates Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/LoadContentCatalogAsync.html Checks for catalog updates and updates only those that have updates. Uses CheckForCatalogUpdates to get the list, then calls UpdateCatalogs with that list. ```csharp IEnumerator CheckCatalogs() { List catalogsToUpdate = new List(); AsyncOperationHandle> checkForUpdateHandle = Addressables.CheckForCatalogUpdates(); checkForUpdateHandle.Completed += op => { catalogsToUpdate.AddRange(op.Result); }; yield return checkForUpdateHandle; if (catalogsToUpdate.Count > 0) { AsyncOperationHandle> updateHandle = Addressables.UpdateCatalogs(catalogsToUpdate); yield return updateHandle; updateHandle.Release(); } checkForUpdateHandle.Release(); } ``` -------------------------------- ### Pre-download dependencies with Addressables.DownloadDependenciesAsync Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/remote-content-predownload.html Use this script to pre-download content for an asset key. It first checks the download size with GetDownloadSizeAsync, and if greater than zero, downloads dependencies with DownloadDependenciesAsync. It logs an error if the download fails and releases the download handle to allow asset loading. This is intended for AssetBundles. ```csharp string key = "assetKey"; // Check the download size AsyncOperationHandle getDownloadSize = Addressables.GetDownloadSizeAsync(key); yield return getDownloadSize; //If the download size is greater than 0, download all the dependencies. if (getDownloadSize.Result > 0) { AsyncOperationHandle downloadDependencies = Addressables.DownloadDependenciesAsync(key); yield return downloadDependencies; if(downloadDependencies.Status == AsyncOperationStatus.Failed) Debug.LogError("Failed to download dependencies for " + key); // we need to release the download handle so the assets can be loaded downloadDependencies.Release(); } ``` -------------------------------- ### Create a concrete AssetReferenceT subclass Source: https://docs.unity3d.com/Packages/com.unity.addressables%404.1/manual/asset-reference-create.html Inherits from AssetReferenceT and passes the GUID string to the base class constructor. Required for versions before Unity 2020.1 or when using CustomPropertyDrawer. ```csharp [Serializable] internal class AssetReferenceMaterial : AssetReferenceT { public AssetReferenceMaterial(string guid) : base(guid) { } } ```