Integrowanie dostawy zasobów (Unity)

Podczas integrowania przesyłania zasobów gry Unity mogą uzyskiwać dostęp do pakietów zasobów za pomocą Addressables lub AssetBundles. Addressables to nowsze i zalecane rozwiązanie do przesyłania zasobów w przypadku gier utworzonych w Unity 2019.4 lub nowszej wersji, natomiast AssetBundles obsługują pakiety zasobów w Unity 2017.4 i 2018.4.

Unity Addressables

W przypadku gier utworzonych w Unity 2019.4 lub nowszej wersji do przesyłania zasobów na Androida należy używać Addressables. Unity udostępnia interfejs Play Asset Delivery (PAD) API do obsługi pakietów zasobów na Androida za pomocą Addressables. Więcej informacji o korzystaniu z Addressables znajdziesz w tych materiałach:

Korzystanie z plików AssetBundle

W przypadku gier utworzonych w Unity 2017.4 i 2018.4 do przesyłania zasobów na Androida można używać plików AssetBundle. Pliki Unity AssetBundle zawierają zasoby serializowane, które mogą być wczytywane przez silnik Unity podczas działania aplikacji. Te pliki są specyficzne dla platformy (np. utworzone na Androida) i mogą być używane w połączeniu z pakietami zasobów. Najczęściej jeden plik AssetBundle jest spakowany w jeden pakiet zasobów, a pakiet ma taką samą nazwę jak AssetBundle. Jeśli chcesz mieć większą elastyczność podczas tworzenia pakietu zasobów, skonfiguruj go za pomocą interfejsu API.

W czasie działania aplikacji użyj klasy Play Asset Delivery for Unity, aby pobrać AssetBundle spakowany w pakiet zasobów.

Wymagania wstępne

  1. Skonfiguruj środowisko programistyczne:

OpenUPM-CLI

Jeśli masz zainstalowany interfejs OpenUPM CLI , możesz zainstalować rejestr OpenUPM za pomocą tego polecenia:

openupm add com.google.play.assetdelivery

OpenUPM

  1. Otwórz ustawienia menedżera pakietów klikając w menu Unity Edit > Project Settings > Package Manager (Edytuj > Ustawienia projektu > Menedżer pakietów).

  2. Dodaj OpenUPM jako rejestr w zakresie w oknie Menedżer pakietów:

    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. Otwórz menu menedżera pakietów, klikając w menu Unity opcję Window > Package Manager.

  4. W menu zakresu menedżera wybierz My Registries (Moje rejestry).

  5. Na liście pakietów wybierz pakiet Google Play Integrity plugin for Unity (Wtyczka Google Play Integrity do Unity) i kliknij Install (Zainstaluj).

Importuj z GitHuba

  1. Pobierz najnowszą wersję .unitypackage z GitHuba.

  2. Zaimportuj plik .unitypackage, klikając w menu Unity Assets > Import package > Custom Package (Zasoby > Importuj pakiet > Własny pakiet) i importując wszystkie elementy.

  1. Utwórz AssetBundles w Unity.

Konfigurowanie AssetBundles za pomocą interfejsu

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

    1. Kliknij Google > Android App Bundle > Asset Delivery Settings (Google > Pakiet aplikacji na Androida > Ustawienia przesyłania zasobów).
    2. Aby wybrać foldery, które bezpośrednio zawierają pliki AssetBundle, kliknij Add Folder (Dodaj folder).

  2. W przypadku każdego pakietu zmień Delivery Mode (Tryb dostawy) na Install Time (Czas instalacji), Fast Follow (Szybkie śledzenie) lub On Demand (Na żądanie). Usuń ewentualne błędy lub zależności i zamknij okno.

  3. Aby utworzyć pakiet aplikacji, kliknij Google > Build Android App Bundle (Google > Utwórz pakiet aplikacji na Androida).

  4. (Opcjonalnie) Skonfiguruj pakiet aplikacji tak, aby obsługiwał różne formaty kompresji tekstur.

Konfigurowanie pakietów zasobów za pomocą interfejsu API

Przesyłanie zasobów możesz skonfigurować za pomocą skryptów edytora, które można uruchamiać w ramach zautomatyzowanego systemu kompilacji.

Użyj klasy AssetPackConfig , aby określić, które zasoby mają być uwzględnione w kompilacji pakietu aplikacji na Androida, a także tryb dostarczania zasobów. Te pakiety zasobów nie muszą zawierać 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ć statycznej BuildBundle metody w klasie Bundletool, aby wygenerować pakiet Android App Bundle z pakietami zasobów, podając BuildPlayerOptions i AssetPackConfig.

Aby uzyskać instrukcje, zapoznaj się z ćwiczeniem praktycznym Używanie Play Asset Delivery w grach Unity.

Integracja z interfejsem Play Asset Delivery Unity API

Interfejs Play Asset Delivery Unity API udostępnia funkcje do żądania pakietów zasobów, zarządzania pobieraniem i uzyskiwania dostępu do zasobów. Najpierw dodaj 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 Plugin-configured asset packs (Pakiety zasobów skonfigurowane za pomocą wtyczki).

Jeśli pakiety zasobów zostały utworzone za pomocą interfejsu API (lub interfejsu wtyczki), wybierz API-configured asset packs.

Interfejs API jest podobny niezależnie od typu przesyłania pakietu zasobów, do którego chcesz uzyskać dostęp. Te czynności są przedstawione na tym schemacie blokowym.

Diagram przepływu pakietu zasobów w interfejsie API

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

Pobieranie pakietu zasobów

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

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

Przesyłanie podczas instalacji

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

Przesyłanie szybkie 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. Użyj metody isDone() , aby sprawdzić, czy pakiet zasobów został już pobrany i jest dostępny, czy wystąpił błąd.

Monitorowanie pobierania

Aby monitorować stan żądania, wysyłaj zapytania do PlayAssetPackRequest obiektu:

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

Pobieranie dużych plików

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 ustawiony na AssetDeliveryStatus.WaitingForWifi , a pobieranie jest wstrzymane. W takim przypadku poczekaj, aż urządzenie połączy się z Wi-Fi, co spowoduje wznowienie pobierania, lub poproś użytkownika o zgodę na pobranie pakietu przez połączenie komórkowe.

Wymagane potwierdzenie użytkownika

Jeśli pakiet ma stan AssetDeliveryStatus.RequiresUserConfirmation, pobieranie nie będzie kontynuowane, dopóki użytkownik nie zaakceptuje okna, które jest wyświetlane za pomocą PlayAssetDelivery.ShowConfirmationDialog(). Ten stan może wystąpić, jeśli aplikacja nie jest rozpoznawana przez Google Play. Pamiętaj, że wywołanie 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 żądania (tylko na żądanie)

Jeśli musisz 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.
}

Wczytywanie zasobów do pamięci

Po zakończeniu żądania użyj jednej z tych funkcji, aby wczytać zasoby do pamięci:

Asynchroniczne żądanie pakietów zasobów

W większości przypadków do asynchronicznego żądania pakietów zasobów i monitorowania postępu należy używać współprogramów, jak pokazano poniżej:

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 interfejsu podstawowej biblioteki Play API

Oto kilka dodatkowych metod interfejsu API, których możesz używać w aplikacji.

Pobieranie wielu pakietów zasobów

Aby pobrać kilka pakietów zasobów naraz, użyj tej funkcji:

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

Monitoruj stany 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 pobierania

Sprawdź rozmiar pakietu zasobów, wykonując asynchroniczne wywołanie do Google Play i ustawiając metodę wywołania zwrotnego, która zostanie wywołana 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();
    }
}

Usuwanie AssetBundles

Możesz usunąć pakiety zasobów typu fast-follow i on-demand, które nie są obecnie wczytane do pamięci. Wykonaj to asynchroniczne wywołanie i ustaw metodę wywołania zwrotnego, która zostanie wywołana po jego 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 przesyłanie zasobów lokalnie i z Google Play.