Loading Sprites at Runtime with Unity Addressables: A Practical Guide
Learn how to cut your Unity game’s initial download size and update assets without rebuilding by using the Addressable Asset System to load sprites at runtime.
28 Aug 2025, 14:26 UTC

Problem: Large initial builds and inflexible content updates
When a Unity game ships, every sprite, audio clip, or prefab referenced directly in scenes ends up in the main player data. This inflates the initial download size and forces a full rebuild whenever you want to tweak a single asset. For live‑service or frequently updated titles, that workflow becomes a bottleneck.
Thesis: Addressables decouple asset references from scenes and enable asynchronous, version‑aware loading
The Unity Addressable Asset System lets you mark assets as "Addressable", assign them a logical key (address or label), and load them at runtime via Addressables.LoadAssetAsync<T>. The system builds separate asset bundles, tracks dependencies, and can serve bundles from a CDN after the initial install. The result is a smaller base build and the ability to push content updates without recompiling the player.
Section 1: Core concepts
Before diving into code, it helps to know three building blocks:
- Addressable Group – a collection of assets that share bundle settings. You create groups in the Addressables Groups window.
- Address or Label – the string you use to request an asset. An address is unique per asset; a label can point to many assets (useful for loading a set).
- Load Handle – the object returned by
LoadAssetAsync. It holds the operation state and must be released when the asset is no longer needed.
Addressables integrates with Unity’s Resource Manager, caches bundles locally, and respects the platform’s streaming settings.
Section 2: Setting up an Addressable sprite
- Open Unity (2022 LTS or newer) and install the Addressables package via the Package Manager (
com.unity.addressables). - Import a sprite (e.g.,
MySprite.png) into the project. - Select the sprite in the Project window, check the Addressable box in the Inspector, and assign an address, for example
sprites/hero/icon. - Optionally, add a label like
ui-iconsif you plan to load multiple icons together. - Open Window → Asset Management → Addressables → Groups to verify the sprite appears in a group (Default Local Group is fine for testing).
When you build the player, Addressables will generate a separate bundle containing this sprite, leaving the main data untouched.
Section 3: Loading and releasing the sprite – worked example
The following MonoBehaviour loads the sprite asynchronously and assigns it to a UI Image component. Place the script on any GameObject in a scene.
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
public class IconLoader : MonoBehaviour
{
[Tooltip("UI Image that will display the loaded sprite")]
public Image targetImage;
// Address assigned in the Inspector for the sprite
private const string SpriteAddress = "sprites/hero/icon";
private AsyncOperationHandle<Sprite> _loadHandle;
private void Start()
{
LoadIcon();
}
private void LoadIcon()
{
_loadHandle = Addressables.LoadAssetAsync<Sprite>(SpriteAddress);
_loadHandle.Completed += OnIconLoaded;
}
private void OnIconLoaded(AsyncOperationHandle<Sprite> handle)
{
if (handle.Status == AsyncOperationStatus.Succeeded)
{
Sprite sprite = handle.Result;
if (targetImage != null)
targetImage.sprite = sprite;
else
Debug.LogWarning("IconLoader: targetImage is not assigned.");
}
else
{
Debug.LogError("Failed to load sprite: " + handle.OperationException);
}
}
private void OnDestroy()
{
// Release the handle to avoid memory leaks
if (_loadHandle.IsValid())
Addressables.Release(_loadHandle);
}
}
Where to run: In the Unity Editor, press Play. No special permissions are required beyond the usual Editor access.
What to check:
- Console: look for the completion log (if you add a
Debug.LoginOnIconLoaded) confirming success. - Profiler → CPU: verify that the main thread spike is short compared to a synchronous
Resources.Loadcall. - Addressables Groups window → Build → New Build → Default Build Script: inspect the generated bundle list; the sprite should appear in its own bundle, not in
sharedassets.
Limitations: If you forget to call Addressables.Release, the bundle stays loaded in memory, causing unnecessary consumption. Always pair each LoadAssetAsync with a release in OnDestroy, OnDisable, or when you explicitly unload the asset.
Section 4: Trade‑offs and practical considerations
Addressables adds build‑time overhead because Unity must analyze dependencies and create bundles. For very small projects, the benefit may not outweigh the extra complexity. Additionally, remote delivery requires a hosting solution (CDN, AWS S3, etc.) and version‑management strategy; testing locally with the Local Load Path is fine, but you must verify the remote workflow before shipping.
Versioning is handled automatically when you enable Content Update in the Addressables settings, but you must increment the Player Version or use a custom manifest to avoid serving stale bundles.
Actionable closing
Start by converting one frequently used sprite (or prefab) to Addressable, load it with the pattern above, and profile the difference in build size and runtime load time. If the results show a smaller initial payload and smooth async loading, expand the approach to other asset types. Remember to always release handles and keep an eye on the Addressables Groups window for duplicate bundles.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.