Guide
Loading Assets at Runtime with Unity Addressables: Step‑by‑Step Guide
Learn how to mark assets as addressable, build content, load them at runtime with proper handle release, and verify memory usage using the Unity Profiler.
Published by Tasadduq Burney
10 Feb 2026, 10:32 UTC
3 min25.2K views0

Desired outcome
Enable runtime loading of assets by address, reduce the initial player build size, and optionally update content without rebuilding the player.
Prerequisites
- Unity 2020.3 LTS or newer (any edition that supports the Package Manager).
- Addressables package version 1.19+ installed via
Window → Package Manager. - Basic familiarity with the Unity Inspector and C# scripting.
- Edit permissions on the project (to mark assets and modify scripts).
Procedure
- Mark assets as addressable
- In the Project window, select a prefab, texture, or other asset.
- In the Inspector, click
Addressableand thenMark as Addressable. - Assign a clear address string, e.g.,
CubePrefab.
- Organize into groups (optional but recommended)
- Open
Window → Asset Management → Addressables → Groups. - Create a new group (right‑click →
Create Group) and drag the marked assets into it. - Set the group’s
Build PathtoLocalBuildPathandLoad PathtoLocalLoadPathfor local testing.
- Open
- Build player content
- With the Addressables window open, click
Build → New Build → Default Build Script. - Unity will generate asset bundles based on the groups and place them in the
Library/com.unity.addressablesfolder. - Note: This step is platform‑specific; repeat if you change the target platform.
- With the Addressables window open, click
- Load the asset at runtime
- Create a C# script (e.g.,
AssetLoader.cs) and attach it to a GameObject in a scene. - Use the following code to load a prefab by its address and instantiate it:
using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; public class AssetLoader : MonoBehaviour { private AsyncOperationHandle _handle; public void LoadCube() { _handle = Addressables.LoadAssetAsync("CubePrefab"); _handle.Completed += OnLoadCompleted; } private void OnLoadCompleted(AsyncOperationHandle handle) { if (handle.Status == AsyncOperationStatus.Succeeded) { GameObject cube = Instantiate(handle.Result); cube.name = "LoadedCube"; // Optionally store the reference for later release } else { Debug.LogError("Failed to load asset: " + handle.OperationException); } } private void OnDestroy() { if (_handle.IsValid()) { Addressables.Release(_handle); } } } - Create a C# script (e.g.,
- Release the handle when the asset is no longer needed
- Call
Addressables.Release(handle)for eachAsyncOperationHandleyou obtained. - Do this in error paths as well (e.g., inside a
catchblock or after a failed load). - Failing to release causes memory leaks because the bundle remains loaded.
- Call
Expected checks
- After calling
LoadAssetAsync, inspect theAsyncOperationHandle.Status; it should beSucceededbefore usinghandle.Result. - Verify that the loaded object is not
null. - Open the Unity Profiler (
Window → Analysis → Profiler), select the Memory module, and look for a temporary spike that disappears after you callRelease. - Check the Console for any address resolution errors (e.g., "Unable to locate address").
Recovery options
- Fallback asset: If loading fails, instantiate a default prefab loaded via
Resources.Loador a hard‑coded reference. - Clear cache: For remote builds, call
Caching.ClearCache()to remove corrupted bundles, then retry the load. - Verify connectivity: Ensure the remote server hosting the bundles is reachable; test with a simple ping or a browser request to the bundle URL.
Limitations
- Addressable builds are platform‑specific; switching target platforms requires rebuilding the content.
- Changing an asset’s group, address, or marking status necessitates a new build; otherwise the player will look for a stale hash and fail to load.
- Remote content depends on correct server configuration (proper MIME types, CORS if needed) and network availability.
Practical verification steps
- Enter Play mode in the Unity Editor.
- Press a UI button that calls
LoadCube()on theAssetLoadercomponent. - Observe the Console: a message like "Load succeeded" (if you added one) or no error indicates success.
- Open the Profiler, watch the Memory tab: you should see a brief increase when the cube is instantiated, returning to baseline after the object is destroyed and the handle released.
- Destroy the instantiated cube (e.g., via another button calling
Destroy) and confirm that the memory drops and no orphaned GameObjects remain in the Hierarchy. - For remote testing, host a dummy bundle on a local web server, set the group’s
RemoteLoadPathto that URL, rebuild, and repeat the steps; simulate a network failure by stopping the server and verify your fallback logic runs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.