Skip to content

Avatarchik/AddressablesServices

 
 

Repository files navigation

openupm

Description

A set of classes to convert Unity Addressables callbacks/coroutine workflow to async/await with UniTask. Unity 2020.1+

Features

  • Static AddressablesService for common Addressables operations.
  • Generic IAddressablesLoader for all asset types loadable from Addressables.
  • Type-safe API with AssetReference, AssetReferenceT<T> and AssetLabelReference.
  • AssetReferenceComponent<T> and extensions to load Component from Addressables.
  • Sync assets loading during gameplay after async preload phase.

Installation

This package can be installed as unity module directly from git url in two ways:

  • By adding following line in Packages/manifest.json:
"com.dre0dru.addressables.services": "https://github.com/dre0dru/AddressablesServices.git#upm",
  • By using Window/Package Manager/Add package from git URL... in Unity:
https://github.com/dre0dru/AddressablesServices.git#upm
openupm add com.dre0dru.addressables.services

This also will install all required dependencies.

If package is installed via openupm then no additional steps are required, otherwise see dependencies.

Dependencies

This package has following dependencies that must be present for package to compile:

Usage

All API has several overloads and accepts following arguments:

  • AddressablesService and IAddressablesLoader:
    • AssetReferenceT<T> (and its inheritors)
    • IEnumerable<AssetReferenceT<T>>
    • params AssetReferenceT<T>[]
  • AddressablesService:
    • AssetReference
    • IEnumerable<AssetReference>
    • params AssetReference[]
    • AssetLabelReference
    • IEnumerable<AssetLabelReference>
    • params AssetLabelReference[]

Important! Addressables will throw exceptions if error occurs during any async operation (e.g. no internet connection when loading remote assets or passing corrupted AssetReference as an argument). These exceptions are not handled by package so it is best to surround any API calls with try catch blocks.

AddressableService

//Example collection of AssetReference and AssetLabelReference
public class ExampleAssets
{
    public AssetReference AssetReference;
    public AssetReferenceSprite AssetReferenceSprite;
    public AssetReferenceGameObject AssetReferenceGameObject;
    public AssetReferenceT<AudioClip> AssetReferenceAudioClip;
    public AssetReferenceComponent<Camera> AssetReferenceComponent;
    public IEnumerable<AssetReference> AssetReferences;

    public AssetLabelReference AssetLabelReference1;
    public AssetLabelReference AssetLabelReference2;
    public IEnumerable<AssetLabelReference> AssetLabelReferences;
}

var assets = new ExampleAssets();

//Mirrors Addressables.InitializeAsync
await AddressablesService.InitializeAsync();

//Gets download size in bytes
long downloadSize = await AddressablesService.GetDownloadSizeAsync(assets.AssetReference);

//Checks if content is downloaded by comparing download size to 0
bool isContentDownloaded = await AddressablesService.IsContentDownloaded(assets.AssetReferenceSprite);

Action<DownloadStatus> onDownloadProgressUpdate = status =>
{
    Debug.Log($"Downloaded {status.DownloadedBytes}/{status.TotalBytes} ({status.Percent * 100}%)");
};
//Downloads remote content with callback for download progress
await AddressablesService.DownloadContentAsync(onDownloadProgressUpdate, assets.AssetLabelReference1,
    assets.AssetLabelReference2);

//Mirrors Addressables.CheckForCatalogUpdates
bool hasUpdates = await AddressablesService.CheckForCatalogUpdatesAsync();

//Mirrors Addressables.UpdateCatalogs
await AddressablesService.UpdateCatalogAsync();

IAddressablesLoader

var assets = new ExampleAssets();

//Create loader for specific asset type
IAddressablesLoader<AudioClip> audioClipLoader =
    new AddressablesLoader<AudioClip>();

//Preload assets
await audioClipLoader.PreloadAssetAsync(assets.AssetReferenceAudioClip);

//Safely extract preloaded asset synchronously
if (audioClipLoader.TryGetAsset(assets.AssetReferenceAudioClip, out AudioClip audioClip))
{
    Debug.Log($"Asset loaded successfully: {audioClip}");
}
else
{
    Debug.Log($"No asset was for preloaded for {assets.AssetReferenceAudioClip.RuntimeKey}");
}

//Check if asset was preloaded
bool isAssetPreloaded = audioClipLoader.IsAssetPreloaded(assets.AssetReferenceAudioClip);

//Or use unsafe asset extraction, will throw exception if no asset was preloaded
AudioClip audioClip = audioClipLoader.GetAsset(assets.AssetReferenceAudioClip);

//Unload unused assets to reduce memory usage
audioClipLoader.UnloadAsset(assets.AssetReferenceAudioClip);
//Or unload all assets that was loaded
audioClipLoader.UnloadAllAssets();

IAddressablesLoader extensions

Check out IAddressablesLoader extensions that provide overloads for IEnumerable arguments and combined operations:

var assets = new ExampleAssets();

IAddressablesLoader<Sprite> spriteLoader =
    new AddressablesLoader<Sprite>();
    
//Preload asset if not preloaded, then get the result
Sprite sprite = await spriteLoader.LoadAssetAsync(assets.SpriteAssetReference);

//Get multiple preloaded assets
IEnumerable<Sprite> sprites = spriteLoader.GetAssets(assets.SpriteAssetReference1, 
                            assets.SpriteAssetReference2);

//Same for multiple assets
IEnumerable<Sprite> sprites = await spriteLoader.LoadAssetsAsync(assets.SpriteAssetReference1,
                            assets.SpriteAssetReference2);

//Safely extract multiple assets
if(spriteLoader.TryGetAssets(assets.SomeSpriteAssetReferencesCollection, out var sprites)
{
    Debug.Log($"Assets loaded successfully: {sprites}");
}

//And many more including params overloads

AssetReferenceComponent

AssetReferenceComponent<T> allows to filter Addressables assets by specific component in Unity Editor. It must be used with IAddressablesLoader<GameObject>.

var assets = new ExampleAssets();

//Create loader for specific asset type
IAddressablesLoader<GameObject> gameObjectLoader =
    new AddressablesLoader<GameObject>();

//AssetReferenceComponent<T> can be passed to IAddressablesLoader<GameObject>
//since it is inherited from AssetReferenceGameObject
await gameObjectLoader.PreloadAssetAsync(assets.AssetReferenceComponent);

//Safely extract preloaded GameObject with Camera component on it
if(gameObjectLoader.TryGetComponent(assets.AssetReferenceComponent, out Camera camera))
{
   var cameraComponent = Object.Instantiate(camera);
}

//Or use unsafe asset extraction, will throw exception if no asset was preloaded
var cameraComponent = gameObjectLoader.GetComponent(assets.AssetReferenceComponent);

License

The software released under the terms of the MIT license.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%