Intégrer Asset Delivery (Unity)

Lors de l'intégration d'Asset Delivery, les jeux Unity peuvent accéder aux packs d'éléments à l'aide d'Addressables ou d'AssetBundles. Les Addressables sont la solution de distribution d'éléments la plus récente et recommandée pour les jeux créés avec Unity 2019.4 ou version ultérieure. Les AssetBundles sont quant à eux compatibles avec les packs d'éléments dans Unity 2017.4 et 2018.4.

Addressables Unity

Les jeux créés avec Unity 2019.4 ou version ultérieure doivent utiliser des Addressables pour la distribution d'éléments sur Android. Unity fournit une API Play Asset Delivery (PAD) pour gérer les packs d'éléments Android à l'aide d'Addressables. Pour en savoir plus sur l'utilisation des Addressables, consultez les pages suivantes :

Utiliser des fichiers AssetBundle

Les jeux créés avec Unity 2017.4 et 2018.4 peuvent utiliser des fichiers AssetBundle pour distribuer des éléments sur Android. Les fichiers AssetBundle d'Unity contiennent des éléments sérialisés qui peuvent être chargés par le moteur Unity pendant l'exécution de l'application. Ces fichiers sont spécifiques à une plate-forme (par exemple, conçus pour Android) et peuvent être utilisés avec des packs d'éléments. Le plus souvent, un fichier AssetBundle est présenté dans un pack d'éléments unique, portant le même nom que l'élément AssetBundle. Si vous souhaitez plus de flexibilité dans la création d'un pack d'éléments, configurez-le à l'aide de l'API.

Au moment de l'exécution, utilisez la classe Play Asset Delivery pour Unity pour récupérer un AssetBundle contenu dans un pack d'éléments.

Conditions préalables

  1. Téléchargez la dernière version du plug-in Play Asset Delivery pour Unity depuis les packages Google pour Unity.

  2. Créez des AssetBundles dans Unity.

Configurer des AssetBundles à l'aide de l'UI

  1. Configurez chaque AssetBundle dans un pack d'éléments :

    1. Sélectionnez Google > Android App Bundle > Paramètres Asset Delivery.
    2. Pour sélectionner des dossiers contenant directement des fichiers AssetBundle, cliquez sur Ajouter un dossier.

  2. Pour chaque bundle, définissez le Mode d'envoi sur Heure d'installation, Distribution rapide ou À la demande. Résolvez les erreurs ou les dépendances, puis fermez la fenêtre.

  3. Sélectionnez Google > Créer un fichier Android App Bundle pour créer l'app bundle.

  4. (Facultatif) Configurez votre app bundle pour qu'il soit compatible avec différents formats de compression de texture.

Configurer des packs d'éléments à l'aide de l'API

Vous pouvez configurer Asset Delivery via des scripts d'éditeur pouvant être exécutés dans un système de compilation automatisé.

Utilisez la classe AssetPackConfig pour définir les éléments à inclure dans un build Android App Bundle, ainsi que le mode d'envoi des éléments. Ces packs d'éléments n'ont pas besoin de contenir d'élément AssetBundle.

public void ConfigureAssetPacks {
   // Creates an AssetPackConfig with a single asset pack, named
   // examplePackName, containing all the files in path/to/exampleFolder.
   var assetPackConfig = new AssetPackConfig();
   assetPackConfig.AddAssetsFolder("examplePackName",
                                   "path/to/exampleFolder",
                                   AssetPackDeliveryMode.OnDemand);

   // Configures the build system to use the newly created assetPackConfig when
   // calling Google > Build and Run or Google > Build Android App Bundle.
   AssetPackConfigSerializer.SaveConfig(assetPackConfig);

   // Alternatively, use BundleTool.BuildBundle to build an App Bundle from script.
   BuildBundle(new buildPlayerOptions(), assetPackConfig);
}

Vous pouvez également utiliser la méthode statique BuildBundle dans la classe Bundletool pour générer un Android App Bundle avec des packs d'éléments, pour BuildPlayerOptions et AssetPackConfig.

Pour suivre un tutoriel guidé, consultez l'atelier de programmation Utilisation de Play Asset Delivery dans les jeux Unity.

Intégrer à l'API Play Asset Delivery d'Unity

L'API Play Asset Delivery d'Unity permet de demander des packs d'éléments, de gérer les téléchargements et d'accéder aux éléments. Veillez d'abord à ajouter le plug-in Unity à votre projet.

Les fonctions que vous utilisez dans l'API dépendent de la manière dont vous avez créé les packs d'éléments.

Si vous avez créé des packs d'éléments à l'aide de l'interface utilisateur du plug-in, sélectionnez Packs d'éléments configurés par plug-in.

Si vous avez créé des packs d'éléments à l'aide de l'API (ou de l'interface utilisateur du plug-in), sélectionnez Packs d'éléments configurés par API.

L'API est semblable quel que soit le type d'envoi du pack d'éléments auquel vous souhaitez accéder. Ces étapes sont présentées dans l'organigramme suivant.

Schéma du flux du pack d'éléments pour l'API

Figure 1. Organigramme illustrant l'accès aux packs d'éléments

Récupérer un pack d'éléments

Importez la bibliothèque Play Asset Delivery et appelez la méthode RetrieveAssetPackAsync() pour télécharger un pack d'éléments si la dernière version du pack n'est pas déjà disponible sur le disque.

using Google.Play.AssetDelivery;

// After download, the assets and/or AssetBundles contained in the asset pack
// are not loaded into memory.
PlayAssetPackRequest request = PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);

Distribution au moment de l'installation

Un pack d'éléments configuré en tant que install-time est disponible immédiatement au lancement de l'application, mais vous devez charger ses éléments dans la mémoire. Consultez Charger des éléments dans la mémoire.

Distribution rapide et à la demande

Ces sections s'appliquent aux packs d'éléments fast-follow et on-demand.

Vérifier l'état

Chaque pack d'éléments est stocké dans un dossier distinct de la mémoire de stockage interne de l'application. Utilisez la méthode isDone() pour déterminer si un pack d'éléments a déjà été téléchargé et est disponible, ou si une erreur s'est produite.

Surveiller le téléchargement

Interrogez l'objet PlayAssetPackRequest pour surveiller l'état de la requête :

// Download progress of request, between 0.0f and 1.0f. The value will always be
// 1.0 for assets delivered as install-time.
// NOTE: A value of 1.0 does not mean that the request has completed, only that
// the DOWNLOADING stage is finished.
float progress = request.DownloadProgress;

// Returns the status of the retrieval request.
// If the request completed successfully, this value should be AssetDeliveryStatus.Available.
// If an error occurred, this value should be AssetDeliveryStatus.Failed.

AssetDelivery status = request.Status;
switch(status) {
    case AssetDeliveryStatus.Pending:
        // Asset pack download is pending - N/A for install-time assets.
    case AssetDeliveryStatus.Retrieving:
        // Asset pack is being downloaded and transferred to app storage.
        // N/A for install-time assets.
    case AssetDeliveryStatus.Available:
        // Asset pack is downloaded on disk but NOT loaded into memory.
        // For PlayAssetPackRequest(), this indicates that the request is complete.
    case AssetDeliveryStatus.Failed:
        // Asset pack retrieval failed.
    case AssetDeliveryStatus.WaitingForWifi:
        // Asset pack retrieval paused until either the device connects via Wi-Fi,
        // or the user accepts the PlayAssetDelivery.ShowConfirmationDialog dialog.
    case AssetDeliveryStatus.RequiresUserConfirmation:
        // Asset pack retrieval paused until the user accepts the
        // PlayAssetDelivery.ShowConfirmationDialog dialog.
    default:
        break;
}

// Returns true if status is AssetDeliveryStatus.Available or AssetDeliveryStatus.Failed.
bool done = request.IsDone;

// If AssetDeliveryStatus.Failed, find more info about the error.
AssetDeliveryErrorCode error = request.Error;

Téléchargements volumineux

Les packs d'éléments de plus de 200 Mo peuvent être téléchargés automatiquement, mais uniquement si l'appareil est connecté au Wi-Fi. Si l'utilisateur n'est pas connecté au Wi-Fi, l'état de la PlayAssetPackRequest est défini sur AssetDeliveryStatus.WaitingForWifi et le téléchargement est temporairement suspendu. Dans ce cas, attendez que l'appareil se connecte au Wi-Fi, puis relancez le téléchargement ou demandez à l'utilisateur d'approuver le téléchargement du paquet via une connexion au réseau mobile.

Confirmation de l'utilisateur requise

Si un pack présente l'état AssetDeliveryStatus.RequiresUserConfirmation, le téléchargement ne se poursuit pas tant que l'utilisateur n'a pas accepté la boîte de dialogue qui s'affiche avec PlayAssetDelivery.ShowConfirmationDialog(). Cet état peut survenir si l'application n'est pas reconnue par Play. Notez que l'appel de PlayAssetDelivery.ShowConfirmationDialog() dans ce cas entraîne la mise à jour de l'application. Une fois la mise à jour effectuée, demandez à nouveau les assets.

if(request.Status == AssetDeliveryStatus.RequiresUserConfirmation
   || request.Status == AssetDeliveryStatus.WaitingForWifi) {
    var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog();
    yield return userConfirmationOperation;

    switch(userConfirmationOperation.GetResult()) {
        case ConfirmationDialogResult.Unknown:
            // userConfirmationOperation finished with an error. Something went
            // wrong when displaying the prompt to the user, and they weren't
            // able to interact with the dialog.
        case ConfirmationDialogResult.Accepted:
            // User accepted the confirmation dialog--an update will start.
        case ConfirmationDialogResult.Declined:
            // User canceled or declined the dialog. It can be shown again.
        default:
            break;
    }
}

Annuler une requête (à la demande uniquement)

Si vous devez annuler la requête avant le téléchargement des packs d'éléments, appelez la méthode AttemptCancel() sur l'objet PlayAssetPackRequest :

// Will only attempt if the status is Pending, Retrieving, or Available; otherwise
// it will be a no-op.
request.AttemptCancel();

// Check to see if the request was successful by checking if the error code is Canceled.
if(request.Error == AssetDeliveryErrorCode.Canceled) {
    // Request was successfully canceled.
}

Charger des éléments dans la mémoire

Une fois la requête terminée, utilisez l'une des fonctions suivantes pour charger des éléments dans la mémoire :

Demander des packs d'éléments de manière asynchrone

Dans la plupart des cas, vous devez utiliser des coroutines pour demander des packs d'éléments de manière asynchrone et surveiller la progression, comme indiqué ci-dessous :

private IEnumerator LoadAssetPackCoroutine(string assetPackName) {

    PlayAssetPackRequest request =
        PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);

    while (!request.IsDone) {
        if(request.Status == AssetDeliveryStatus.WaitingForWifi) {
            var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog();

            // Wait for confirmation dialog action.
            yield return userConfirmationOperation;

            if((userConfirmationOperation.Error != AssetDeliveryErrorCode.NoError) ||
               (userConfirmationOperation.GetResult() != ConfirmationDialogResult.Accepted)) {
                // The user did not accept the confirmation. Handle as needed.
            }

            // Wait for Wi-Fi connection OR confirmation dialog acceptance before moving on.
            yield return new WaitUntil(() => request.Status != AssetDeliveryStatus.WaitingForWifi);
        }

        // Use request.DownloadProgress to track download progress.
        // Use request.Status to track the status of request.

        yield return null;
    }

    if (request.Error != AssetDeliveryErrorCode.NoError) {
        // There was an error retrieving the pack. For error codes NetworkError
        // and InsufficientStorage, you may prompt the user to check their
        // connection settings or check their storage space, respectively, then
        // try again.
        yield return null;
    }

    // Request was successful. Load the asset pack into memory.
    AssetBundleCreateRequest assetBundleCreateRequest = request.LoadAssetBundleAsync(path/to/exampleBundle);
    yield return assetBundleCreateRequest;
    AssetBundle assetBundle = assetBundleCreateRequest.assetBundle;

Pour en savoir plus sur la gestion des erreurs, consultez la liste des codes d'erreur.

Autres méthodes de l'API Play Core

Voici quelques méthodes d'API supplémentaires que vous pouvez utiliser dans votre application.

Récupérer plusieurs packs d'éléments

Pour récupérer plusieurs packs d'éléments en même temps, utilisez la fonction suivante :

// assetPackNames is an array of strings corresponding to asset packs.
PlayAssetPackBatchRequest batchRequest = PlayAssetDelivery.RetrieveAssetPackBatchAsync(<IListstring> assetPackNames);

Surveillez l'état de chaque requête en inspectant le champ Dictionary des états :

// Dictionary of AssetPackStates, with the asset pack name as the key.
Dictionary<string, PlayAssetPackRequest> requests = batchRequest.Requests;

// Returns true if all requests are complete.
bool requestComplete = batchRequest.IsDone;

Vérifier la taille du téléchargement

Vérifiez la taille d'un pack d'éléments en effectuant un appel asynchrone vers Google Play et en définissant une méthode de rappel pour la fin de l'opération :

public IEnumerator GetDownloadSize() {
   PlayAsyncOperation<long> getSizeOperation =
   PlayAssetDelivery.GetDownloadSize(assetPackName);

   yield return getSizeOperation;
   if(operation.Error != AssetDeliveryErrorCode.NoError) {
       // Error while retrieving download size.
    } else {
        // Download size is given in bytes.
        long downloadSize = operation.GetResult();
    }
}

Supprimer les AssetBundles

Vous pouvez supprimer les packs d'éléments à distribution rapide et à la demande qui ne sont actuellement pas chargés dans la mémoire. Effectuez l'appel asynchrone suivant et définissez une méthode de rappel pour la fin de l'opération :

PlayAsyncOperation<string> removeOperation = PlayAssetDelivery.RemoveAssetPack(assetBundleName);

removeOperation.Completed += (operation) =>
            {
                if(operation.Error != AssetDeliveryErrorCode.NoError) {
                    // Error while attempting to remove AssetBundles.
                } else {
                    // Files were deleted OR files did not exist to begin with.
                }
            };

Étapes suivantes

Testez Asset Delivery en local et à partir de Google Play.