Understanding the Addressable Asset System
The Addressable Asset System provides a framework for loading assets by a unique address rather than a file path. Unlike traditional asset bundling, it abstracts the location of assets, allowing content to be updated post-release and loaded dynamically without manual dependency tracking. It handles the dependency chain automatically, ensuring that all required assets are available when requested.
Setting Up the Environment
- Install the Package: Navigate to
Window>Package Manager. Switch the registry to "Packages: Unity Registry" and locate "Addressables". ClickInstall. - Initialize Groups: Open the Groups window via
Window>Asset Management>Addressables>Groups. ClickCreate Addressables Settingsif prompted. This generates the necessary configuration files in your project.
Configuring Asset Groups
Assets are organized into Groups, which define how they are packaged and loaded.
- In the Addressables Groups window, select the
Groupspanel. - Click
Create New Group>Packed Assets. Name the group logically, such asUI_ElementsorEnvironment_Assets. - Select the assets in your Project window, drag them into the Group window, or right-click the assets and select
Addressables>Add to Addressables. Each asset will be assigned a unique key (the address).
Implementation Examples
Loading a GameObject Prefab
The following example demonstrates loading a prefab asynchronously using a string key. This approach decouples the code from specific asset locations.
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class PrefabLoader : MonoBehaviour
{
public string prefabKey = "PowerUp_Item";
void Start()
{
StartCoroutine(LoadPrefabInstance());
}
System.Collections.IEnumerator LoadPrefabInstance()
{
AsyncOperationHandle<GameObject> loadHandle = Addressables.LoadAssetAsync<GameObject>(prefabKey);
yield return loadHandle;
if (loadHandle.Status == AsyncOperationStatus.Succeeded)
{
GameObject instance = Instantiate(loadHandle.Result);
instance.name = "LoadedPowerUp";
Debug.Log("Prefab instantiated successfully.");
}
else
{
Debug.LogError("Failed to load prefab: " + loadHandle.OperationException);
}
}
}
Loading and Releasing a Scene
Scenes can be loaded additively or singly. Its crucial to release the handle or the scene instance to free memory.
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
public class LevelManager : MonoBehaviour
{
public AssetReference levelReference;
AsyncOperationHandle<SceneInstance> currentLevelHandle;
public void LoadNewLevel()
{
currentLevelHandle = Addressables.LoadSceneAsync(levelReference, LoadSceneMode.Single);
currentLevelHandle.Completed += OnLevelReady;
}
void OnLevelReady(AsyncOperationHandle<SceneInstance> op)
{
if (op.Status == AsyncOperationStatus.Succeeded)
{
Debug.Log("Level loaded: " + op.Result.Scene.name);
}
}
public void UnloadCurrentLevel()
{
if (currentLevelHandle.IsValid())
{
Addressables.UnloadSceneAsync(currentLevelHandle);
}
}
}
Async/Await Pattern
For modern C# syntax, the async/await pattern can be utilized with the .Task property of the operation handle.
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class TextureFetcher : MonoBehaviour
{
public string textureAddress = "MainMenu_Background";
async void FetchTextureData()
{
AsyncOperationHandle<Texture2D> fetchHandle = Addressables.LoadAssetAsync<Texture2D>(textureAddress);
try
{
await fetchHandle.Task;
Texture2D result = fetchHandle.Result;
Debug.Log($"Texture dimensions: {result.width}x{result.height}");
}
catch (System.Exception e)
{
Debug.LogError($"Error fetching texture: {e.Message}");
}
finally
{
if (fetchHandle.IsValid())
Addressables.Release(fetchHandle);
}
}
}
Advantages in Production
- Content Updates: Deliver updated assets to players without requiring a full application redeployment via Content Delivery Networks (CDN).
- Memory Efficiency:Assets are loaded on demand. The system provides tools to analyze memory usage and dependencies, preventing duplicate loads.
- Streamlined Workflow: Artists and designers can mark assets as Addressable directly in the editor, removing the need for programmers to hardcode resource paths.