Skip to content

Addressable Asset Loading

This example shows how to use Addressables for async loading of localized assets.

Setup

  1. Install Addressables package
  2. Create an Addressable Asset Table (instead of regular Asset Table)
  3. Mark your assets as Addressable in the Addressables Groups window

Basic Async Loading

csharp
using Lexis;
using Lexis.Addressables;
using UnityEngine;
using UnityEngine.UI;

public class AddressableExample : MonoBehaviour
{
    [SerializeField] private Image splashImage;

    async void Start()
    {
        Localization.Initialize();
        AddressableLocalization.RegisterTablesFromSettings();

        // Load localized sprite asynchronously
        Sprite splash = await AddressableLocalization.GetAssetAsync<Sprite>("ui", "splash");
        splashImage.sprite = splash;
    }

    void OnDestroy()
    {
        AddressableLocalization.ReleaseAll();
    }
}

Preloading During Loading Screen

csharp
using Lexis;
using Lexis.Addressables;
using UnityEngine;
using UnityEngine.UI;

public class LoadingScreen : MonoBehaviour
{
    [SerializeField] private Slider progressBar;
    [SerializeField] private Text progressText;

    async void Start()
    {
        Localization.Initialize();
        AddressableLocalization.RegisterTablesFromSettings();

        // Preload all assets for current locale
        var progress = new Progress<float>(p =>
        {
            progressBar.value = p;
            progressText.text = $"Loading... {p:P0}";
        });

        await AddressableAssetPreloader.PreloadLocaleAsync(
            Localization.CurrentLocale.Code,
            progress);

        // All assets now loaded, proceed to game
        LoadNextScene();
    }
}

Callback-Based Loading

For Unity versions without async/await support:

csharp
using Lexis.Addressables;
using UnityEngine;
using UnityEngine.UI;

public class CallbackExample : MonoBehaviour
{
    [SerializeField] private Image flagImage;
    [SerializeField] private Sprite loadingSprite;

    void LoadFlag()
    {
        // Show loading placeholder
        flagImage.sprite = loadingSprite;

        // Load with callbacks
        AddressableLocalization.GetAssetAsync<Sprite>("flags", "country",
            sprite =>
            {
                // Success: apply loaded sprite
                flagImage.sprite = sprite;
            },
            error =>
            {
                // Error: log and keep placeholder
                Debug.LogError($"Failed to load flag: {error}");
            });
    }
}

Progress Tracking with Handle

csharp
using Lexis.Addressables;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using System.Collections;

public class HandleExample : MonoBehaviour
{
    IEnumerator LoadWithProgress()
    {
        var handle = AddressableLocalization.GetAssetHandle<Sprite>("ui", "large-background");

        while (!handle.IsDone)
        {
            Debug.Log($"Loading: {handle.PercentComplete:P0}");
            yield return null;
        }

        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            backgroundImage.sprite = handle.Result;
        }
    }
}

Preload Events

csharp
using Lexis.Addressables;
using UnityEngine;

public class PreloadMonitor : MonoBehaviour
{
    void OnEnable()
    {
        AddressableAssetPreloader.OnPreloadStarted += OnStarted;
        AddressableAssetPreloader.OnAssetPreloaded += OnAssetLoaded;
        AddressableAssetPreloader.OnPreloadCompleted += OnCompleted;
    }

    void OnDisable()
    {
        AddressableAssetPreloader.OnPreloadStarted -= OnStarted;
        AddressableAssetPreloader.OnAssetPreloaded -= OnAssetLoaded;
        AddressableAssetPreloader.OnPreloadCompleted -= OnCompleted;
    }

    void OnStarted(string locale, int assetCount)
    {
        Debug.Log($"Started preloading {assetCount} assets for {locale}");
    }

    void OnAssetLoaded(string key, object asset)
    {
        Debug.Log($"Loaded: {key}");
    }

    void OnCompleted(string locale, int success, int failed)
    {
        Debug.Log($"Completed: {success} loaded, {failed} failed");
    }
}

Component-Based Loading

Use built-in components for automatic loading:

csharp
// AddressableLocalizedSpriteComponent
// - Attach to GameObject with Image
// - Configure TableId and AssetKey
// - Set FallbackSprite for loading state
// - Auto-loads on enable, releases on disable

// AddressableLocalizedAudioComponent
// - Attach to GameObject with AudioSource
// - Same configuration pattern

// AddressableLocalizedPrefabComponent
// - Instantiates localized prefab
// - Destroys when locale changes

Memory Management

csharp
using Lexis.Addressables;
using UnityEngine;

public class MemoryManager : MonoBehaviour
{
    void OnSceneChange()
    {
        // Release all loaded addressable assets
        AddressableLocalization.ReleaseAll();
    }

    void OnLocaleChanged()
    {
        // Release preloaded assets for old locale
        AddressableAssetPreloader.ReleasePreloaded();

        // Preload for new locale
        _ = PreloadNewLocale();
    }

    async Task PreloadNewLocale()
    {
        await AddressableAssetPreloader.PreloadLocaleAsync(
            Localization.CurrentLocale.Code);
    }
}

Best Practices

  1. Preload during loading screens - Avoid hitches during gameplay
  2. Release when done - Prevent memory leaks
  3. Use fallback sprites - Show placeholder while loading
  4. Handle errors gracefully - Network issues can cause failures
  5. Group by locale - Organize Addressables groups for efficient loading

Professional Unity Development Tools