Интегрируйте доставку ресурсов (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. Для получения информации об использовании 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 CLI , вы можете установить реестр OpenUPM с помощью следующей команды:

openupm add com.google.play.assetdelivery

OpenUPM

  1. Откройте настройки менеджера пакетов , выбрав в меню Unity пункт «Редактировать» > «Настройки проекта» > «Менеджер пакетов» .

  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 пункт Assets > Import package > Custom Package и импортировав все элементы.

  1. Создание AssetBundles в Unity .

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

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

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

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

  3. Для создания пакета приложения выберите Google > Build Android App Bundle .

  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 .

Для получения пошагового руководства см. Codelab по использованию Play Asset Delivery в играх Unity .

Интеграция с API Unity для доставки игровых ресурсов

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

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

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

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

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

Схема потока ресурсов для плагина

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

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

Импортируйте библиотеку Play Asset Delivery и вызовите метод RetrieveAssetBundleAsync() для получения объекта 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);

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

Пакеты ресурсов, настроенные как устанавливаемые во install-time становятся доступны сразу после запуска приложения. Для загрузки сцены из 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]);

Быстрая доставка по запросу.

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

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

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

Отслеживайте загрузку

Для отслеживания статуса запроса выполните запрос к объекту PlayAssetBundleRequest :

// 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.ShowConfirmationDialog dialog.
    case AssetDeliveryStatus.RequiresUserConfirmation:
        // Asset pack retrieval paused until the user accepts the
        // PlayAssetDelivery.ShowConfirmationDialog dialog.
    default:
        break;
}

Большие файлы для скачивания

Пакеты ресурсов размером более 200 МБ могут загружаться автоматически, но только через Wi-Fi. Если пользователь не подключен к Wi-Fi, статус PlayAssetBundleRequest устанавливается в 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;
    }
}

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

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

Запрашивайте пакеты ресурсов асинхронно.

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

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;

Для получения дополнительной информации об обработке ошибок см. список кодов AssetDeliveryErrorCodes ).

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

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

Проверить размер загружаемого файла

Проверьте размер AssetBundle, выполнив асинхронный вызов к 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();
    }
}

Удалить AssetBunds

Вы можете удалить быстро загружаемые и загружаемые по запросу 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.