Integrowanie dostawy zasobów (Unity)

Dzięki integracji przesyłania zasobów gry na Unity mogą korzystać z pakietów zasobów za pomocą Addressables lub AssetBundles. Rozwiązania adresowe to najnowsze i zalecane rozwiązanie do przesyłania zasobów w grach utworzonych na platformie Unity w wersji 2019.4 lub nowszej, natomiast AssetBundles obsługuje pakiety zasobów w wersjach Unity 2017.4 i 2018.4.

Unity Addressables

Gry stworzone w Unity w wersji 2019.4 lub nowszej powinny przesyłać zasoby na Androida za pomocą Addressables. Unity udostępnia interfejs Play Asset Delivery (PAD) API do obsługi pakietów zasobów Androida przy użyciu funkcji Addressable. Informacje o korzystaniu z adresów znajdziesz tutaj:

Używaj plików AssetBundle

Gry utworzone na platformie Unity 2017.4 i 2018.4 mogą używać plików AssetBundle do przesyłania zasobów na Androida. Pliki AssetBundle na platformie Unity zawierają zserializowane zasoby, które mogą być ładowane przez silnik Unity, gdy aplikacja jest uruchomiona. Pliki te są związane z konkretną platformą (np. na Androida) i można ich używać w połączeniu z pakietami zasobów. Jeden plik AssetBundle jest zazwyczaj pakowany w pojedynczy pakiet zasobów, którego nazwa jest taka sama jak w przypadku AssetBundle. Jeśli potrzebujesz większej elastyczności przy tworzeniu pakietu zasobów, skonfiguruj go za pomocą interfejsu API.

Aby pobrać obiekt AssetBundle w pakiecie zasobów, w czasie działania użyj klasy Play Asset Delivery dla Unity.

Wymagania wstępne

  1. Pobierz najnowszą wersję wtyczki Unity Play Asset Delivery z pakietów Google dla Unity.

  2. Utwórz AssetBundles w Unity.

Konfigurowanie AssetBundles za pomocą interfejsu użytkownika

  1. Skonfiguruj każdy pakiet zasobów w pakiecie zasobów:

    1. Wybierz Google > Pakiet Android App Bundle > Ustawienia dostawy zasobów.
    2. Aby wybrać foldery zawierające bezpośrednio pliki AssetBundle, kliknij Dodaj folder.

  2. W przypadku każdego pakietu zmień Tryb dostarczania na Czas instalacji, Szybkie śledzenie lub Na żądanie. Wyeliminuj błędy lub zależności i zamknij okno.

  3. Wybierz Google > Utwórz pakiet Android App Bundle, aby utworzyć pakiet aplikacji.

  4. (Opcjonalnie) Skonfiguruj pakiet aplikacji pod kątem obsługi różnych formatów kompresji tekstur.

Skonfiguruj pakiety zasobów za pomocą interfejsu API

Dostarczanie zasobów można skonfigurować za pomocą skryptów edytora, które można uruchamiać w ramach automatycznego systemu kompilacji.

Użyj klasy AssetPackConfig, aby określić, które zasoby mają zostać uwzględnione w kompilacji pakietu Android App Bundle, oraz określić tryb ich dostarczania. Te pakiety nie muszą zawierać obiektu 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);
}

Możesz też użyć metody statycznej BuildBundle w klasie Bundletool do wygenerowania pakietu Android App Bundle z pakietami zasobów w zależności od właściwości BuildPlayerOptions i AssetPackConfig.

Samouczek znajdziesz w artykule Korzystanie z funkcji Play Asset Delivery w grach Unity (Unity) w Codelabs.

Integracja z interfejsem Play Asset Delivery Unity API

Interfejs Play Asset Delivery Unity API umożliwia wysyłanie żądań pakietów zasobów, zarządzanie pobieraniem oraz uzyskiwanie dostępu do zasobów. Pamiętaj, aby najpierw dodać wtyczkę Unity do projektu.

Funkcje, których używasz w interfejsie API, zależą od sposobu utworzenia pakietów zasobów.

Jeśli pakiety zasobów zostały utworzone za pomocą interfejsu wtyczki, wybierz Pakiety zasobów skonfigurowane pod kątem wtyczek.

Jeśli pakiety zasobów zostały utworzone za pomocą interfejsu API (lub interfejsu wtyczki), wybierz Pakiety zasobów skonfigurowane przez interfejs API.

Interfejs API jest podobny niezależnie od typu przesyłania pakietu zasobów, do którego chcesz uzyskać dostęp. Te kroki przedstawiono na poniższym schemacie blokowym.

Diagram przepływu pakietu zasobów dla interfejsu API

Rysunek 1. Schemat blokowy dostępu do pakietów zasobów

Pobieranie pakietu zasobów

Jeśli najnowsza wersja pakietu nie jest jeszcze dostępna na dysku, zaimportuj bibliotekę Play Asset Delivery i wywołaj metodę RetrieveAssetPackAsync(), aby pobrać pakiet zasobów.

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

Dostawa podczas instalacji

Pakiet zasobów skonfigurowany jako install-time jest dostępny od razu po uruchomieniu aplikacji, ale musisz wczytać jego zasoby w pamięci. Zobacz Wczytywanie zasobów do pamięci.

Szybkie śledzenie i na żądanie

Te sekcje dotyczą pakietów zasobów fast-follow i on-demand.

Sprawdź stan

Każdy pakiet zasobów jest przechowywany w osobnym folderze w pamięci wewnętrznej aplikacji. Aby sprawdzić, czy pakiet zasobów został już pobrany i jest dostępny, oraz czy wystąpił błąd, użyj metody isDone().

Monitorowanie pobierania

Wyślij zapytanie do obiektu PlayAssetPackRequest, aby monitorować stan żądania:

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

Duże pliki do pobrania

Pakiety zasobów większe niż 200 MB mogą być pobierane automatycznie, ale tylko wtedy, gdy urządzenie jest połączone z Wi-Fi. Jeśli użytkownik nie korzysta z Wi-Fi, stan PlayAssetPackRequest jest ustawiany na AssetDeliveryStatus.WaitingForWifi, a pobieranie jest wstrzymane. W takim przypadku zaczekaj, aż urządzenie połączy się z Wi-Fi, wznowi pobieranie lub poproś użytkownika o zgodę na pobranie pakietu przez sieć komórkową.

Wymagane potwierdzenie użytkownika

Jeśli pakiet ma stan AssetDeliveryStatus.RequiresUserConfirmation, pobieranie nie rozpocznie się, dopóki użytkownik nie zaakceptuje okna ze stanem PlayAssetDelivery.ShowConfirmationDialog(). Ten stan może się pojawić, jeśli aplikacja nie zostanie rozpoznana przez Google Play. Pamiętaj, że wywołanie metody PlayAssetDelivery.ShowConfirmationDialog() w tym przypadku spowoduje zaktualizowanie aplikacji. Po aktualizacji ponownie poproś o zasoby.

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

Anulowanie prośby (tylko na żądanie)

Jeśli chcesz anulować żądanie przed pobraniem pakietów zasobów, wywołaj metodę AttemptCancel() w obiekcie 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.
}

Wczytaj zasoby do pamięci

Gdy żądanie zostanie zrealizowane, użyj jednej z tych funkcji, aby wczytać zasoby do pamięci:

Asynchroniczne żądania pakietów zasobów

W większości przypadków należy używać Coroutines, aby asynchronicznie wysyłać żądania pakietów zasobów i monitorować postępy, zgodnie z tymi przykładami:

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;

Więcej informacji o obsłudze błędów znajdziesz na liście kodów błędów.

Inne metody Play Core API

Poniżej znajdziesz kilka dodatkowych metod interfejsu API, których możesz używać w swojej aplikacji.

Pobierz wiele pakietów zasobów

Aby pobrać wiele pakietów zasobów jednocześnie, użyj tej funkcji:

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

Monitoruj stan każdego żądania, sprawdzając Dictionary stanów:

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

Sprawdzanie rozmiaru pobieranego pliku

Sprawdź rozmiar pakietu zasobów, wywołując asynchroniczne wywołanie w Google Play i ustawiając metodę wywołania zwrotnego po zakończeniu operacji:

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

Usuń pakiety AssetBundles

Możesz usunąć pakiety zasobów szybkich i na żądanie, które nie są obecnie wczytywane w pamięci. Wykonaj poniższe wywołanie asynchroniczne i ustaw metodę wywołania zwrotnego po zakończeniu:

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

Dalsze kroki

Przetestuj dostawę zasobów lokalnie i z Google Play.