Integrowanie dostawy zasobów (Unity)

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

Unity Addressables

Gry utworzone w wersji Unity 2019.4 lub nowszej powinny korzystać z adresowalności na potrzeby przesyłania zasobów na Androida. Unity udostępnia interfejs Play Asset Delivery (PAD) do obsługi pakietów zasobów na Androida za pomocą usługi Addressables. Informacje o używaniu adresowalnych reklam znajdziesz w tych materiałach:

Używanie plików AssetBundle

Gry utworzone w Unity 2017.4 i 2018.4 mogą używać plików AssetBundle do dostarczania zasobów na Androida. Pliki AssetBundle w Unity zawierają serializowane zasoby, które mogą być wczytywane przez silnik Unity podczas działania aplikacji. Te pliki są przeznaczone do konkretnej platformy (np. Androida) i można ich używać w połączeniu z pakietami komponentów. Najczęściej jeden plik AssetBundle jest pakowany w jeden pakiet komponentów, który ma tę samą nazwę co plik AssetBundle. Jeśli chcesz mieć większą elastyczność podczas tworzenia pakietu komponentów, skonfiguruj go za pomocą interfejsu API.

W czasie wykonywania kodu użyj klasy Play Asset Delivery for Unity, aby pobrać pakiet AssetBundle zapakowany w pakiet zasobów.

Wymagania wstępne

  1. Skonfiguruj środowisko programistyczne:

OpenUPM-CLI

Jeśli masz zainstalowany interfejs wiersza poleceń OpenUPM, 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 opcję menu Unity Edytuj > Ustawienia projektu > Menedżer pakietów.

  2. Dodaj OpenUPM jako ograniczony rejestr do okna Menedżera 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, wybierając w menu Unity opcję Okno > Menedżer pakietów.

  4. W menu zakresu menedżera wybierz Moje rejestry.

  5. Na liście pakietów wybierz pakiet Google Play Integrity plugin for Unity i kliknij Zainstaluj.

Importowanie z GitHuba

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

  2. Zaimportuj plik .unitypackage, wybierając opcję menu Unity Zasoby > Importuj pakiet > Własny pakiet i importując wszystkie elementy.

  1. Utwórz pakiety zasobów w Unity.

Konfigurowanie pakietów komponentów za pomocą interfejsu

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

    1. Kliknij Google > Pakiet aplikacji na Androida > Ustawienia dostarczania zasobów.
    2. Aby wybrać foldery, które bezpośrednio zawierają pliki AssetBundle, kliknij Dodaj folder.

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

  3. Aby utworzyć pakiet aplikacji, wybierz 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

Dostarczanie zasobów możesz 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 aplikacji na Androida, a także sposób ich dostarczania. Te pakiety komponentów nie muszą zawierać pliku 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 metody BuildBundle w klasie Bundletool, aby wygenerować pakiet aplikacji na Androida z pakietami zasobów, pod warunkiem że użyjesz opcji BuildPlayerOptionsAssetPackConfig.

Przewodnik znajdziesz w ćwiczeniach z programowania Używanie Play Asset Delivery w grachach w Unity (wersja na komputer).

Integracja z interfejsem Play Asset Delivery API w Unity

Interfejs Play Asset Delivery API w Unity udostępnia funkcje umożliwiające żądanie pakietów zasobów, zarządzanie pobieraniem i dostęp do zasobów. Najpierw dodaj do projektu wtyczkę Unity.

Funkcje używane w interfejsie API zależą od sposobu utworzenia pakietów komponentów.

Jeśli pakiety komponentów zostały utworzone za pomocą interfejsu wtyczki, wybierz Pakiety komponentów skonfigurowane w pluginie.

Jeśli pakiety komponentów zostały utworzone za pomocą interfejsu API (lub interfejsu użytkownika w pluginie), wybierz pakiety komponentów skonfigurowane za pomocą interfejsu API.

Interfejs API jest podobny niezależnie od typu dostawy pakietu komponentów, do którego chcesz uzyskać dostęp. Te kroki są pokazane na poniższym schemacie.

Schemat przepływu interfejsu API dla pakietu zasobów

Rysunek 1. Schemat procesu uzyskiwania dostępu do pakietów komponentów

Pobieranie pakietu komponentów

Zaimportuj bibliotekę komponentów usługi Play i wywołaj metodę RetrieveAssetPackAsync(), aby pobrać pakiet komponentó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 załadować jego komponenty do pamięci. Zapoznaj się z sekcją Ładowanie zasobów do pamięci.

Szybkie śledzenie i dostawy na żądanie

Te sekcje dotyczą pakietów komponentów fast-followon-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 komponentów został już pobrany i jest dostępny, czy też wystąpił błąd.

Monitorowanie pobierania

Aby śledzić stan prośby, prześlij zapytanie do obiektu 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;

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 jest połączony z siecią Wi-Fi, stan PlayAssetPackRequest jest ustawiony na AssetDeliveryStatus.WaitingForWifi, a pobieranie jest wstrzymane. W takim przypadku poczekaj, aż urządzenie połączy się z siecią Wi-Fi, a pobieranie zostanie wznowione, lub poproś użytkownika o pozwolenie 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 wyświetlonego okna dialogowego z PlayAssetDelivery.ShowConfirmationDialog(). Ten stan może wystąpić, jeśli aplikacja nie jest rozpoznawana przez Google Play. Pamiętaj, że wywołanie funkcji PlayAssetDelivery.ShowConfirmationDialog() 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 w przypadku wersji na żądanie)

Jeśli chcesz anulować żądanie przed pobraniem pakietów zasobów, wywołaj metodę AttemptCancel() obiektu 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 komponentów do pamięci;

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

Prośba o pakiety komponentów w tle

W większości przypadków należy użyć routin, aby asynchronicznie żądać pakietów zasobów i monitorować postępy, 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ługiwaniu błędów znajdziesz na liście kodów błędów.

Inne metody interfejsu Play Core API

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

Pobieranie wielu pakietów komponentów

Aby pobrać wiele pakietów komponentó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żdej prośby, 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;

Sprawdź rozmiar pobierania

Sprawdź rozmiar pakietu zasobów, wykonując asynchroniczne wywołanie 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();
    }
}

Usuwanie AssetBundles

Możesz usunąć pakiety komponentów szybkiego śledzenia i na żądanie, które nie są obecnie załadowane 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

Testuj dostarczanie zasobów lokalnie i z Google Play.