Cómo integrar Asset Delivery (Unity)

Cuando integres la función de Asset Delivery, los juegos de Unity podrán acceder a paquetes de recursos usando Addressables o archivos AssetBundle. Los Addressables son la solución de entrega de recursos más reciente y recomendada para juegos compilados con Unity 2019.4 o versiones posteriores, mientras que los AssetBundles brindan compatibilidad con paquetes de recursos en Unity 2017.4 y 2018.4.

Addressables de Unity

Los juegos compilados con Unity 2019.4 o versiones posteriores deben usar Addressables para la entrega de recursos en Android. Unity ofrece una API de Play Asset Delivery (PAD) para controlar los paquetes de recursos de Android usando Addressables. Si quieres obtener más información para usar Addressables, consulta lo siguiente:

Cómo usar archivos AssetBundle

Los juegos compilados con Unity 2017.4 y 2018.4 pueden usar archivos AssetBundle para entregar recursos en Android. Los archivos AssetBundle de Unity contienen recursos serializados que el motor de Unity puede cargar mientras se ejecuta la app. Esos archivos son específicos de cada plataforma (por ejemplo, compilados para Android) y se pueden usar junto con paquetes de recursos. Por lo general, se empaqueta un archivo AssetBundle en un solo paquete de recursos con el mismo nombre que el archivo AssetBundle. Si quieres más flexibilidad para crear un paquete de recursos, configúralo con la API.

Durante el tiempo de ejecución, usa la clase Play Asset Delivery para Unity para recuperar un archivo AssetBundle incluido en un paquete de recursos.

Requisitos previos

  1. Descarga la versión más reciente del complemento de Play Asset Delivery para Unity desde paquetes de Google para Unity.

  2. Crea archivos AssetBundle en Unity.

Cómo configurar archivos AssetBundle con la IU

  1. Configura cada archivo AssetBundle en un paquete de recursos:

    1. Selecciona Google > Android App Bundle > Asset Delivery Settings.
    2. Para seleccionar carpetas que contengan directamente archivos AssetBundle, haz clic en Add Folder.

  2. Para cada paquete, cambia el modo de entrega en Delivery Mode a Install Time, Fast Follow u On Demand. Resuelve los errores o dependencias, y cierra la ventana.

  3. Selecciona Google > Build Android App Bundle para compilar el paquete de aplicación.

  4. Opcional: Configura el paquete de aplicación para que sea compatible con diferentes formatos de compresión de texturas.

Cómo configurar paquetes de recursos con la API

Puedes configurar Asset Delivery a través de secuencias de comandos del editor, que se pueden ejecutar como parte de un sistema de compilación automatizado.

Usa la clase AssetPackConfig para definir qué recursos incluirás en una compilación de Android App Bundle y el modo de entrega de los recursos. Esos paquetes de recursos no necesitan contener un 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);
}

También puedes usar el método estático BuildBundle en la clase Bundletool para generar un Android App Bundle con paquetes de recursos, dadas BuildPlayerOptions y AssetPackConfig.

Si deseas obtener un instructivo guiado, consulta Cómo usar Play Asset Delivery en el Codelab de juegos de Unity.

Cómo realizar la integración con la API de Play Asset Delivery

La API de Unity de Play Asset Delivery proporciona la funcionalidad para solicitar paquetes de recursos, administrar descargas y acceder a los recursos. Asegúrate de primero agregar el complemento para Unity a tu proyecto.

Las funciones que usas en la API dependen de cómo creaste los paquetes de recursos.

Si creaste paquetes de recursos con la IU del complemento, selecciona Paquetes de recursos configurados por complementos.

Si creaste paquetes de recursos con la API (o la IU del complemento), selecciona Paquetes de recursos configurados por API.

La API es similar sin importar el tipo de entrega del paquete de recursos al que desees acceder. Estos pasos se muestran en el siguiente diagrama de flujo.

Diagrama de flujo del paquete de recursos para la API

Figura 1: Diagrama de flujo para acceder a paquetes de recursos

Cómo recuperar un paquete de recursos

Importa la Biblioteca de Play Asset Delivery y llama al método RetrieveAssetPackAsync() para descargar un paquete de recursos si la versión más reciente del paquete aún no está disponible en el disco.

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);

Cómo realizar la entrega durante la instalación

Un paquete de recursos configurado como install-time está disponible de inmediato para el lanzamiento de la app, pero debes cargar sus recursos en la memoria. Consulta Cómo cargar recursos en la memoria.

Cómo realizar entregas rápidas y a pedido

Estas secciones se aplican a los paquetes de recursos fast-follow y on-demand.

Cómo comprobar el estado

Cada paquete de recursos se almacena en una carpeta independiente del almacenamiento interno de la app. Usa el método isDone() para determinar si un paquete de recursos ya se descargó y está disponible, o si se produjo un error.

Cómo supervisar la descarga

Consulta el objeto PlayAssetPackRequest para supervisar el estado de la solicitud:

// 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.ShowCellularDataConfirmation 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;

Descargas grandes

Los paquetes de recursos de más de 150 MB pueden descargarse automáticamente, pero solo si el dispositivo está conectado a Wi-Fi. Si el usuario no está conectado a una red Wi-Fi, el estado PlayAssetPackRequest se establece en AssetDeliveryStatus.WaitingForWifi y la descarga se pausa. En este caso, espera hasta que el dispositivo se conecte a Wi-Fi, reanuda la descarga o pídele al usuario que apruebe la descarga del paquete mediante una conexión móvil.

if(request.Status == AssetDeliveryStatus.WaitingForWifi) {
    var userConfirmationOperation = PlayAssetDelivery.ShowCellularDataConfirmation();
    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. In this case, we recommend
            // developers wait for Wi-Fi before attempting to download again.
            // You can get more info by calling GetError() on the operation.
        case ConfirmationDialogResult.Accepted:
            // User accepted the confirmation dialog - download will start
            // automatically (no action needed).
        case ConfirmationDialogResult.Declined:
            // User canceled or declined the dialog. Await Wi-Fi connection, or
            // re-prompt the user.
        default:
            break;
    }
}

Cómo cancelar una solicitud (solo a pedido)

Si necesitas cancelar la solicitud antes de que se descarguen los paquetes de recursos, llama al método AttemptCancel() en el objeto 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.
}

Cómo cargar recursos en la memoria

Una vez que se complete la solicitud, usa una de estas funciones para cargar recursos en la memoria:

Cómo solicitar paquetes de recursos de manera asíncrona

En la mayoría de los casos, debes usar Corrutinas para solicitar paquetes de recursos de manera asíncrona y supervisar el progreso, como se muestra a continuación:

private IEnumerator LoadAssetPackCoroutine(string assetPackName) {

    PlayAssetPackRequest request =
        PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);

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

            // 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;

Para obtener más información sobre cómo resolver errores, consulta la lista de códigos de error.

Otros métodos de la API de Play Core

Estos son algunos métodos de API adicionales que te recomendamos usar en tu app.

Cómo recuperar varios paquetes de recursos

Para recuperar varios paquetes de recursos a la vez, usa la siguiente función:

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

Supervisa los estados de cada solicitud mediante la inspección del Dictionary de los estados:

// 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;

Cómo comprobar el tamaño de descarga

Para verificar el tamaño de un paquete de recursos, realiza una llamada asíncrona a Google Play y configura un método de devolución de llamada para cuando finalice la operación:

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();
    }
}

Cómo quitar AssetBundles

Puedes quitar paquetes de recursos rápidos y a pedido que no se cargan actualmente en la memoria. Realiza la siguiente llamada asíncrona y configura un método de devolución de llamada para cuando se complete:

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.
                }
            };

Siguiente paso

Prueba la entrega de recursos de forma local y desde Google Play.