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.

Debes implementar la API según el tipo de entrega del paquete de recursos al que deseas acceder. Estos pasos se muestran en el siguiente diagrama de flujo.

Diagrama de flujo del paquete de recursos para el complemento

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

Cómo recuperar AssetBundles

Importa la Biblioteca de Play Asset Delivery y llama al método RetrieveAssetBundleAsync() para recuperar un AssetBundle.

using Google.Play.AssetDelivery;

// Loads the AssetBundle from disk, downloading the asset pack containing it if necessary.
PlayAssetBundleRequest bundleRequest = PlayAssetDelivery.RetrieveAssetBundleAsync(asset-bundle-name);

Cómo realizar la entrega durante la instalación

Los paquetes de recursos configurados como install-time están disponibles de inmediato cuando se lanza la app. Puedes usar lo siguiente para cargar una escena desde AssetBundle:

AssetBundle assetBundle = bundleRequest.AssetBundle;

// You may choose to load scenes from the AssetBundle. For example:
string[] scenePaths = assetBundle.GetAllScenePaths();
SceneManager.LoadScene(scenePaths[path-index]);

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 isDownloaded() para determinar si ya se descargó un paquete de recursos.

Cómo supervisar la descarga

Consulta el objeto PlayAssetBundleRequest 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 will only signify the download is complete. It will still need to be loaded.
float progress = bundleRequest.DownloadProgress;

// Returns true if:
//   * it had either completed the download, installing, and loading of the AssetBundle,
//   * OR if it has encountered an error.
bool done = bundleRequest.IsDone;

// Returns status of retrieval request.
AssetDeliveryStatus status = bundleRequest.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.Loading:
        // Asset pack is being loaded.
    case AssetDeliveryStatus.Loaded:
        // Asset pack has finished loading, assets can now be loaded.
        // For PlayAssetBundleRequest(), this indicates that the request is complete.
    case AssetDeliveryStatus.Failed:
        // Asset pack retrieval has 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;
}

Descargas grandes

Los paquetes de recursos de más de 150 MB pueden descargarse automáticamente, pero solo mediante Wi-Fi. Si el usuario no está conectado a una red Wi-Fi, el estado PlayAssetBundleRequest 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(bundleRequest.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 los AssetBundles se carguen a la memoria, llama al método AttemptCancel() en PlayAssetBundleRequest:

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

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

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 LoadAssetBundleCoroutine(string assetBundleName) {

    PlayAssetBundleRequest bundleRequest =
        PlayAssetDelivery.RetrieveAssetBundleAsync(assetBundleName);

    while (!bundleRequest.IsDone) {
        if(bundleRequest.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(() => bundleRequest.Status != AssetDeliveryStatus.WaitingForWifi);
        }

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

        yield return null;
    }

    if (bundleRequest.Error != AssetDeliveryErrorCode.NoError) {
        // There was an error retrieving the bundle. 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. Retrieve AssetBundle from request.AssetBundle.
    AssetBundle assetBundle = bundleRequest.AssetBundle;

Para obtener más información sobre cómo manejar los errores, consulta la lista de AssetDeliveryErrorCodes.

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 comprobar el tamaño de descarga

Para verificar el tamaño de un AssetBundle, realiza una llamada asíncrona en 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 los AssetBundles rápidos y a pedido que no se cargan actualmente a 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.