Интегрированная доставка активов (Unity),Интегрированная доставка активов (Unity)

При интеграции доставки ресурсов игры Unity могут получать доступ к пакетам ресурсов с помощью Addressables или AssetBundles. Addressables — это новейшее и рекомендуемое решение для доставки ресурсов для игр, созданных с помощью Unity 2019.4 или более поздней версии, а AssetBundles обеспечивают поддержку пакетов ресурсов в Unity 2017.4 и 2018.4.

Адреса Unity

Игры, созданные с помощью Unity 2019.4 или более поздней версии, должны использовать Addressables для доставки ресурсов на Android. Unity предоставляет API-интерфейс Play Asset Delivery (PAD) для обработки пакетов ресурсов Android с помощью Addressables. Информацию об использовании адресных устройств см. в следующих разделах:

Используйте файлы AssetBundle

Игры, созданные с помощью Unity 2017.4 и 2018.4, могут использовать файлы AssetBundle для доставки ресурсов на Android. Файлы Unity AssetBundle содержат сериализованные ресурсы, которые могут быть загружены движком Unity во время работы приложения. Эти файлы зависят от платформы (например, созданы для Android) и могут использоваться в сочетании с пакетами ресурсов. Чаще всего один файл AssetBundle упаковывается в один пакет ресурсов, при этом пакет использует то же имя, что и AssetBundle. Если вам нужна большая гибкость при создании пакета ресурсов, настройте пакет ресурсов с помощью API .

Во время выполнения используйте класс Play Asset Delivery for Unity , чтобы получить AssetBundle, упакованный в пакет ресурсов.

Предварительные условия

  1. Настройте среду разработки:

OpenUPM-CLI

Если у вас установлен интерфейс командной строки OpenUPM, вы можете установить реестр OpenUPM с помощью следующей команды:

openupm add com.google.play.assetdelivery

ОпенУПМ

  1. Откройте настройки менеджера пакетов , выбрав пункт меню Unity Edit > Project Settings > Package Manager .

  2. Добавьте OpenUPM в качестве реестра с определенной областью в окно диспетчера пакетов:

    Name: package.openupm.com
    URL: https://package.openupm.com
    Scopes: com.google.external-dependency-manager
      com.google.play.common
      com.google.play.core
      com.google.play.assetdelivery
      com.google.android.appbundle
    
  3. Откройте меню диспетчера пакетов , выбрав пункт меню Unity «Окно» > «Диспетчер пакетов» .

  4. Установите раскрывающийся список области менеджера, чтобы выбрать «Мои реестры» .

  5. Выберите плагин Google Play Integrity для пакета Unity из списка пакетов и нажмите «Установить» .

Импорт из GitHub

  1. Загрузите последнюю версию .unitypackage с GitHub.

  2. Импортируйте файл .unitypackage , выбрав пункт меню Unity «Активы» > «Импортировать пакет» > «Пользовательский пакет» и импортировав все элементы.

  1. Создайте AssetBundles в Unity .

Настройка AssetBundles с помощью пользовательского интерфейса

  1. Настройте каждый AssetBundle в пакете ресурсов:

    1. Выберите Google > Пакет приложений Android > Настройки доставки активов .
    2. Чтобы выбрать папки, которые непосредственно содержат файлы AssetBundle, нажмите «Добавить папку» .

  2. Для каждого пакета измените Режим доставки на Время установки , Быстрое выполнение или По требованию . Устраните все ошибки или зависимости и закройте окно.

  3. Выберите Google > Создать пакет приложений для Android , чтобы создать пакет приложений.

  4. (Необязательно) Настройте пакет приложений для поддержки различных форматов сжатия текстур .

Настройте пакеты ресурсов с помощью API

Вы можете настроить доставку ресурсов с помощью сценариев редактора, которые можно запускать как часть автоматизированной системы сборки.

Используйте класс AssetPackConfig , чтобы определить, какие ресурсы включить в сборку Android App Bundle, а также режим доставки ресурсов. Эти пакеты ресурсов не обязательно должны содержать 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);
}

Вы также можете использовать статический метод BuildBundle в классе Bundletool для создания пакета приложений Android с пакетами ресурсов, заданными BuildPlayerOptions и AssetPackConfig .

Подробное руководство см. в разделе «Использование доставки ресурсов Play в Codelab игр Unity» .

Интеграция с Play Asset Delivery Unity API

API Play Asset Delivery Unity предоставляет функции для запроса пакетов ресурсов, управления загрузками и доступа к ресурсам. Обязательно сначала добавьте плагин Unity в свой проект.

Функции, которые вы используете в API, зависят от того, как вы создали пакеты ресурсов.

Если вы создали пакеты ресурсов с помощью пользовательского интерфейса плагина , выберите Пакеты ресурсов, настроенные подключаемым модулем .

Если вы создали пакеты ресурсов с помощью API (или пользовательского интерфейса плагина) , выберите пакеты ресурсов, настроенные с помощью API .

API аналогичен независимо от типа доставки пакета ресурсов, к которому вы хотите получить доступ. Эти шаги показаны на следующей блок-схеме.

Блок-схема пакета ресурсов для API

Рисунок 1. Блок-схема доступа к пакетам ресурсов

Получить пакет активов

Импортируйте библиотеку доставки ресурсов Play и вызовите метод RetrieveAssetPackAsync() чтобы загрузить пакет ресурсов, если последняя версия пакета еще не доступна на диске.

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

Доставка во время установки

Пакет ресурсов, настроенный для установки во install-time сразу же доступен при запуске приложения, но вам необходимо загрузить его ресурсы в память. См. Загрузка ресурсов в память .

Быстрая доставка и доставка по требованию

Эти разделы относятся к пакетам ресурсов fast-follow и on-demand .

Проверить статус

Каждый пакет ресурсов хранится в отдельной папке во внутренней памяти приложения. Используйте метод isDone() чтобы определить, был ли уже загружен и доступен пакет ресурсов или произошла ошибка.

Следить за загрузкой

Запросите объект PlayAssetPackRequest , чтобы отслеживать состояние запроса:

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

Большие загрузки

Пакеты ресурсов размером более 200 МБ можно загрузить автоматически, но только если устройство подключено к Wi-Fi. Если пользователь не подключен к Wi-Fi, для статуса PlayAssetPackRequest устанавливается значение AssetDeliveryStatus.WaitingForWifi , а загрузка приостанавливается. В этом случае либо подождите, пока устройство подключится к Wi-Fi и возобновит загрузку, либо запросите у пользователя разрешение на загрузку пакета через сотовую связь.

Требуется подтверждение пользователя

Если пакет имеет статус AssetDeliveryStatus.RequiresUserConfirmation , загрузка не продолжится, пока пользователь не примет диалоговое окно, отображаемое с помощью PlayAssetDelivery.ShowConfirmationDialog() . Этот статус может возникнуть, если приложение не распознается Play. Обратите внимание, что вызов PlayAssetDelivery.ShowConfirmationDialog() в этом случае приводит к обновлению приложения. После обновления запросите активы еще раз.

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

Отменить запрос (только по требованию)

Если вам необходимо отменить запрос до загрузки пакетов ресурсов, вызовите метод AttemptCancel() объекта 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.
}

Загрузка ресурсов в память

После завершения запроса используйте одну из этих функций для загрузки ресурсов в память:

  • Используйте PlayAssetPackRequest.GetAssetLocation() чтобы получить объект AssetLocation . Это обеспечивает путь, смещение и размер ресурса, чтобы его можно было загрузить с диска.
  • Если ресурс является AssetBundle, вы можете использовать удобный метод PlayAssetPackRequest.LoadAssetBundleAsync(assetPath) . Путь к активу, который вы передаете, должен соответствовать пути к AssetBundle из пакета ресурсов. Это вернет AssetBundleCreateRequest .

Асинхронный запрос пакетов ресурсов

В большинстве случаев вам следует использовать Coroutines для асинхронного запроса пакетов ресурсов и отслеживания прогресса, как показано ниже:

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;

Дополнительную информацию об обработке ошибок см. в списке кодов ошибок .

Другие методы Play Core API

Ниже приведены некоторые дополнительные методы API, которые вы можете использовать в своем приложении.

Получить несколько пакетов активов

Чтобы получить несколько пакетов ресурсов одновременно, используйте следующую функцию:

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

Отслеживайте статусы каждого запроса, проверяя Dictionary состояний:

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

Проверьте размер загрузки

Проверьте размер пакета ресурсов, выполнив асинхронный вызов Google Play и установив метод обратного вызова на момент завершения операции:

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

Удалить AssetBundles

Вы можете удалить пакеты ресурсов быстрого отслеживания и по требованию, которые в данный момент не загружены в память. Выполните следующий асинхронный вызов и установите метод обратного вызова на момент его завершения:

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

Следующие шаги

Тестируйте доставку ресурсов локально и из Google Play.