Addressable Asset Loading
This example shows how to use Addressables for async loading of localized assets.
Setup
- Install Addressables package
- Create an Addressable Asset Table (instead of regular Asset Table)
- 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 changesMemory 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
- Preload during loading screens - Avoid hitches during gameplay
- Release when done - Prevent memory leaks
- Use fallback sprites - Show placeholder while loading
- Handle errors gracefully - Network issues can cause failures
- Group by locale - Organize Addressables groups for efficient loading
