Skip to content Skip to sidebar Skip to footer

La MEGA-Guida italiana all’uso degli Addressables in Unity

Quando si parla di Addressables in Unity si tende generalmente a considerarlo un argomento ostico e di difficile comprensione in quanto molto complesso nella configurazione, nella gestione e nella distribuzione degli Assets.
Tale funzionalità permette di spostare gli asset dalla build principale ad un pacchetto esterno (locale e/o remoto) al fine di poterlo aggiornare senza ricompilare la build ma anche per permettere una migliore gestione dei caricamenti e della distribuzione dei dati.

Di seguito proponiamo quindi una guida passo-passo all’implementazione degli Addressables in un progetto Unity nuovo, per principianti ma anche esperti che vogliono approfondire alcuni aspetti secondari dell’argomento.

La guida si basa sulla versione 2.3.16 del pacchetto Addressables e realizzata con Unity 6.000.0.43f1

Configurazione progetto e utilizzo degli Addressables

Installazione

  • Installare l’ultima versione disponibile del pacchetto Addressables di Unity tramite Package Manager
  • I file di installazione degli Addressables si troveranno quindi ora in \Assets\AddressableAssetsData (utile per la configurazione del sistema è il file “AddressableAssetSettings.asset” in essa contenuto

Configurazione

  • Tramite Windows -> Asset Management -> Addressables -> Groups creare un nuovo gruppo (ad esempio “Animations”), renderlo di default ed eliminare quello creato inizialmente da Unity.
  • Verificare le impostazioni del gruppo tramite Inspector, soprattutto le due path LocalPath e RemotePath.
  • Trascinare dentro il gruppo appena creato i propri assets. Per ogni asset selezionare poi la voce “Simplify Addressables Name” tramite tasto destro sull’asset stesso (questo renderà più semplice richiamare gli asset specifici tramite nome da codice).
  • Creare uno script in Unity per inizializzare e verificare il caricamento di asset Addressables caricati in modo asincrono, nelle due modalità di seguito.
  • CARICAMENTO ASINCRONO TRAMITE REFERENCE: Per caricare un Asset presente nel gruppo degli Addressables creare una variabile AssetReference nello script ed associare, tramite trascinamento, l’asset a cui è riferito direttamente dal gruppo Addressable. Eseguire quindi in modo asincrono la funzione LoadAssetAsync della reference stessa, come segue:
public class AddressableLoader : MonoBehaviour
{
    // Riferimento all'Asset Addressable (ad esempio, un prefab)
    public AssetReference assetReference;

    // Start è un metodo sincrono, ma usiamo un metodo asincrono separato per caricare l'asset
    async void Start()
    {   
       // Carica l'asset in modo asincrono
        await LoadAssetAsync();
    }

    // Metodo asincrono per caricare l'asset
    private async Task LoadAssetAsync()
    {
        // Avvia il caricamento asincrono dell'asset
        AsyncOperationHandle<GameObject> handle = assetReference.LoadAssetAsync<GameObject>();

        // Attendi che il caricamento finisca
        await handle.Task;

        // Controlla se il caricamento è stato completato con successo
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            // Instanzia l'asset caricato nella scena
            GameObject asset = handle.Result;
            Instantiate(asset, Vector3.zero, Quaternion.identity);
        }
        else
        {
            Debug.LogError("Errore nel caricamento dell'asset.");
        }
    }
}
  • CARICAMENTO ASINCRONO TRAMITE NOME: per poter caricare un asset tramite nome è possibile invece usare, nel modo del tutto analogo al precedente, la funzione Addressables.LoadAssetAsync al quale si passa il nome dell’Asset (il nome semplificato presente nel gruppo di appartenenza).
public class AddressableLoader : MonoBehaviour
{
    // Indica l'ID dell'asset Addressable che vuoi caricare (ad esempio, il prefab)
    public string assetAddress;

    void Start()
    {
        // Carica l'asset asincronicamente
        LoadAssetAsync();
    }

    // Metodo per caricare l'asset asincronicamente
    private void LoadAssetAsync()
    {
        // Chiamata asincrona per caricare l'asset
        AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(assetAddress);

        // Quando il caricamento è completato, gestiamo il risultato
        handle.Completed += (op) =>
        {
            if (op.Status == AsyncOperationStatus.Succeeded)
            {
                // Instanzia l'asset caricato nella scena
                GameObject asset = op.Result;
                Instantiate(asset, Vector3.zero, Quaternion.identity);
            }
            else
            {
                Debug.LogError("Errore nel caricamento dell'asset.");
            }
        };
    }
}
  • Eseguendo il codice verrà avviato il caricamento dell’Asset desiderato ed, in questo caso, istanziato in scena.

Pubblicazione su server remoto

  • E’ necessario ora procedere alla pubblicazione degli Addressables su server remoto e specificarne l’indirizzo in Unity. Per fare questo accedere a Window -> Asset Managaement -> Addressables -> Profiles e modificare il profilo di Default.
    Nello specifico lasciare le impostazioni di Local su Built-in mentre modificare Remote impostandolo su Custom. A questo punto:
    • Specificare il percorso di Remote.LoadPath con un indirizzo remoto (es: https://www.desdinova.it/TestAddressables/[BuildTarget] – E’ la directory in cui risiederanno Addressables e Catalog del progetto.
    • Lasciare Remote.BuildPath impostata di base su ServerData/[BuildTarget] – E’ la directory presente nella cartella di progetto in cui verranno salvati gli Addressables e il Catalog da copiare successivamente nel percorso remoto.
  • Accedere a Window -> Asset Management -> Addressables -> Settings e verificare che la voce Build & Load Paths sia impostata su Remote:
    • Se necessario abilitare l’opzione “Enable Json Catalog” per rendere il file di Catalog su disco leggibile, anche se l’operazione genera un file più grande e non compresso.
    • Verificare che sia abilitato “Build Remote Catalog”.
  • Accedere agli Addressables Groups e aprire la tendina Build in alto a destra poi New Build > Default Build Script. Verranno generati immediatamente gli Addressables nella directory RemoteBuildPath (lasciata a ServerData\[BuildTarget]) che andranno caricati in remoto sul server.
    Questa procedura deve essere sempre eseguita ad ogni modifica degli Asset presenti negli Addressables, sia essa una modifica strutturale oppure solamente il colore di un materiale.
  • A questo punto, compilando la build, il progetto accederà all’apertura degli Addressables direttamente da remoto. Qualora ci fossero problemi di configurazione del server o di percorsi, gli Assets non verranno caricati generando errori a runtime.

Note generali

Build di Addressables differenti per differenti piattaforme

E’ da tenere presente che Unity specifica, e predilige, l’impostazioni delle path con il suffisso [BuildTaget] in questo modo aiuta a discriminare eventuali build per altre piattaforme. Se si compila per web, quella sottodirectory avrà suffisso “WebGL” mentre per Windows avrà “StandaloneWindows64” e così via.
NOTA: E’ da ricordare come build per piattaforme differenti richiedano Addressables compilati in modo specifico, non è possibile utilizzare Addressables di una build WebGL tramite una build Windows.

Testare gli Addressables remoti in Editor locale

E’ bene indicare che eseguendo invece l’applicativo tramite il tasto Play nell’editor, il progetto utilizzerà gli Addressables Local e non quelli remoti. Per modificare questo comportamento accedere alla schermata Addressables Groups, cliccare sulla tendina Play Mode Script in alto a destra (a fianco di Build) e scegliere Use Existing Build (…) il quale permette di associare la build appena creata al Play Mode di Unity corrente potendo così testare gli Addressables remoti facilmente in editor (e verificare eventuali errori).

E’ da precisare che Use Existing Build non caricare gli Addressables buildati in locale nella directory locale del server perchè questi file devono essere serviti via HTTP/S, non può caricare file locali (file://) in Play Mode o runtime. Quindi i files andranno sempre copiati nelal directory remota specificata nel profilo.
Se si vuole fare in modo che il Play Mode utilizzi il file buildati per il server ma nelal directory locale allora impostare la directory di build come servita da un web server (es. IIS, Unity Hosting Service, Node.js, XAMPP, etc).

Conoscere il peso di download del singolo Asset

Se si vuole conoscere il peso del download di uno specifico Assets usare Addressables.GetDownloadSizeAsync(assetName) che in modo asincrono ritorna la dimensione dell’Asset in bytes. E’ da indicare che ritorna il peso complessivo del gruppo in cui è incluso l’asset e non solo l’Assets, a meno che non sia in un gruppo specifico.
La particolarità di questa funzione è che se l’Asset è già in cache il valore ritornato è 0 ed è quindi utile per vedere se un Asset è già stata caricato prima di quel momento oppure è fresco (vedere punto seguente).

Gestione della cache remota

E’ doveroso fare alcune considerazione sulla cache degli Addressables.
Per verificare se un file di Asset è realmente in cache la prima cosa che si può pensare è quella di cancellare tale file dal server remoto e quindi provare ad eseguire la chiamata a quell’Asset nuovamente. Purtroppo questo tentativo fallirà con degli errori in quanto non basta cancellare il solo file ma serve cancellare anche i files Catalog remoti (questo perchè Unity trova i files di catalogo, legge il GUID del bundle necessario ma non trovandolo genera errore). Il sistema di cache si attiva unicamente quando TUTTO il catalogo ed i suoi files non sono più presenti (o cambiati).
E’ per questo motivo che quando il sistema di build degli Addressable genera nomi di bundle nuovi mantiene comunque quelli vecchi in quanto potrebbero essere ancora in cache di qualche utilizzatore. E’ bene quindi non cancellare mai tali file dal server remoto oppure farlo in modo consapevole (ad esempio dopo una build che necessita una forzatura completa degli assets).

Vantaggi della compressione degli Asset

E’ da indicare quanto gli Addressables espongano un vantaggio indiretto: quello di essere compressi e quindi facilitare la distribuzione. Da alcuni test è possibile ad esempio individuare come una animazione di Unity (.anim) passi da 15MB a circa 300KB compressi, oppure da 130MB a 8MB. L’utilizzo degli Addressables quindi è consigliato anche solo per la gestione e la distribuzione di Asset di grandi dimensioni (per questo motivo ad esempio Nintendo Switch SDK consiglia l’utilizzo proprio degli Addressables di Unity per distribuire DLC).

Utilissimo per verificare la compressione dei dati è il tool Addressable Report (tab Explore) che si trova in Window > Assets Management > Addressables > Groups > Tools > Window > Addressable Reports.

MimeType degli Addressables del server remoto

Quando si usano gli Addressables in remoto è bene verificare di abilitare i seguenti MimeType sul server (verificare che non siano già presenti, in tal caso il server potrebbe generare un errore 500 in quanto non contempla dichiarazioni doppie):

<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".hash" mimeType="text/plain" />   
<mimeMap fileExtension=".bundle" mimeType="application/octet-stream" />
<mimeMap fileExtension=".bin" mimeType="application/octet-stream" />

Problemi CORS sul browser nel richiamare gli Addressables remoti

Uno degli annosi problemi che spesso si riscontra nell’uso degli Addressables remoti è della complessità dovuta alla protezione CORS (Cross-Origin Resource Share). Per ovviare a questo problema è possibile specificare alcuni header del server in modo che vengano abilitate le origini, i metodi e le autorizzazioni necessarie (di default molto restrittive), ad esempio:

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type,Authorization" />

Aggiornare una build Addressables

Per eseguire una build degli Assets del progetto sono presenti due possibilità in Addressables Group > Build (in alto a destra). Di seguito indichiamo la caratteristiche di entrambe e quando usarle per ottimizzare il proprio lavoro e la distribuzione:

  • New Build -> Default Build Script: da usare la prima volta che si generano gli Addressables e successivamente quando si vogliono rigenerare i cataloghi e quando si sono fatte modifiche strutturali agli Addressables (ad esempio nomi, gruppi, etc) – Tutti i client dovranno riscaricare tutti gli Asset necessari in quanto anche i contenuti non cambiati veranno rigenerati.
  • Build -> Update a Previous Build: da usare quando si fanno aggiornamenti leggeri (si cambia un materiale, si aggiunge una animazione, etc) e quando si vuole risparmiare banda/caricamenti sul client – Genera solo bundle nuovi o aggiornati creando un nuovo catalogo permettendo aggiornamenti incrementali e leggeri (in produzione).

Accenti nei nomi degli Addressables in una build Release

Può capitare la necessità di gestire nomi di Addressables con accenti. Per una migliore gestione della nomenclatura interna (quindi unicamente usata dal sistema) è possibile specificare che il catalogo usi nomi basati su GUID e non Full Path (default), oppure Dynamic.

Per fare questo accedere al file di configurazione Addressables Asset Settings > Catalog > Internal Asset Naming Mode > GUID (oppure Dynamic).
Questa proprietà permette di far usare al sistema nomi interni numerici e non testuali aumentando anche il fattore di compressione del buildato finale (per questo motivo consigliato in un profilo Release e non di sviluppo).

Addressables in un progetto WebGL

Gestione della cache in una build WebGL

Per quanto riguarda build in WebGL è doveroso riportare alcuni metodi che purtroppo non funzionano (generando errori) in quanto WebGL usa un sistema di cache del browser e non locale alla build (non avendo accesso a filesystem del dispositivo):

  • Caching.ClearCache() – ed in generale tutte le funzioni della classe Caching.
  • Addressables.CleanBundleCache()
  • Addressables.ClearDependencyCacheAsync(…)

In questi casi è quindi consigliato utilizzare la direttiva di compilazione if !UNITY_WEBGL per aggirare problemi di supporto alle funzionie in una build WebGL.

Configurazione della memoria in una build WebGL

Di default il valore della memoria minima usata da WebAssembly riservata alle sue operazioni è di 32MB, oggettivamente troppo pochi per la memorizzazione di Addressables. Per questo motivo è consigliato impostare la memoria minima usata da WebAssembly in un progetto WebGL ad un valore di 256MB. Se sono presenti grandi files come video o animazioni è bene considerare di portarlo anche a 512MB.

Il parametro lo si trova in Edit -> Project Settings -> Player -> Publishing Settings -> WebAssembly Language Features -> Initial Memory Size (MB)

Gestire l’errore “RangeError: Maximum call stack size exceeded” all’avvio di una build WebGL

Durante la lavorazione di un progetto WebGL che implementa gli Addressables può capitare (non così raramente) di imbattersi nell’errore del browser “RangeError: Maximum call stack size exceeded“. Si tratta di un errore generico ed è legato a conflitti che avvengono a livello di cache. Spesso è legato alla creazione di una “Update a Previous Build” e non ad una “New Build”.

Per risolvere il problema è necessario vagliare le seguenti soluzioni:

  • Aumentare la memoria minima di WebAssembly (vedere paragrafo precedente).
  • Verificare che in Edit -> Project Settings -> Player -> Publishing Settings -> Decompression Fallback sia disattivato.
  • Cancellare manualmente la cache della pagina che da problemi, direttamente dal browser (premere Ctrl+F5).
  • Nei DevTools del browser accedere a Application -> Storage -> IndexedDB -> UnityCache e cliccare il pulsante Delete Database.
  • Nei DevTools del browser accedere a Application -> Storage -> Cache Storage ed eliminare il file corrispondente al progetto incriminato (tasto destro -> Delete). Solitamente inizia con “UnityCache_…”
  • In ultima istanza eseguire un “Clean Build” degli Addressables invece di un Update.

Gestire l’errore “Error while downloading Asset Bundle: CRC Mismatch. Provided 4644c445, calculated f8db947d from data. Will not load AssetBundle”

Questo errore viene generato quando non vi è più corrispondenza tra il catalogo Addressables compilato e quello che l’applicativo si aspetta di caricare. Spesso succede quando si modificano delle impopstazioni di base del catalogo. La soluzione è quella di eseguire il comando “Clear Build Cache > All”, ribuildare gli Addressables ed eventualmente ribuildare l’applicativo.

Copyright © Desdinova ® / PIVA 03799780162 / Non è una testata giornalistica.
Tutti i diritti riservati ai legittimi proprietari, anche ove non citati.