Tích hợp tính năng phân phối tài sản (Unity)

Khi tích hợp tính năng phân phối tài sản, trò chơi Unity có thể truy cập vào các gói tài sản bằng cách sử dụng Addressable hoặc AssetBundle. Addressable là giải pháp phân phối tài sản mới và được đề xuất cho trò chơi được xây dựng bằng Unity 2019.4 trở lên, trong khi đó AssetBundle hỗ trợ các gói tài sản trong Unity 2017.4 và 2018.4.

Addressable của Unity

Các trò chơi được xây dựng bằng Unity 2019.4 trở lên nên sử dụng Addressable để phân phối tài sản trên Android. Unity cung cấp Play Asset Delivery (PAD) API để xử lý các gói tài sản Android bằng Addressable. Để biết thông tin về cách sử dụng Addressable, hãy xem:

Sử dụng tệp AssetBundle

Các trò chơi được xây dựng bằng Unity 2017.4 và 2018.4 có thể sử dụng các tệp AssetBundle để phân phối tài sản trên Android. Các tệp AssetBundle chứa tài sản chuyển đổi tuần tự được tải bằng công cụ Unity trong khi ứng dụng chạy. Các tệp này là tuỳ theo nền tảng (ví dụ: được tạo dành cho Android) và có thể sử dụng kết hợp với gói tài sản. Trường hợp phổ biến nhất là một tệp AssetBundle được đóng gói thành gói tài sản duy nhất, đồng thời cũng lấy tên là AssetBundle. Nếu muốn linh hoạt hơn trong việc tạo gói tài sản, hãy định cấu hình gói tài sản đó bằng cách sử dụng API.

Khi chạy, hãy sử dụng lớp Play Asset Delivery cho Unity để truy xuất gói AssetBundle đã đóng trong gói tài sản.

Điều kiện tiên quyết

  1. Tải bản phát hành mới nhất của Play Asset Delivery Unity Plugin từ các gói Google dành cho Unity.

  2. Tạo AssetBundles trong Unity.

Sử dụng giao diện người dùng để định cấu hình AssetBundle

  1. Định cấu hình từng AssetBundle trong gói tài sản:

    1. Chọn Google > Android App Bundle > Cài đặt phân phối nội dung.
    2. Để chọn thư mục chứa trực tiếp tệp AssetBundle, nhấp vào Thêm thư mục.

  2. Đối với mỗi gói, hãy thay đổi Chế độ phân phối thành Thời gian cài đặt, Theo dõi nhanh hoặc Theo yêu cầu. Giải quyết lỗi hoặc phần phụ thuộc và đóng cửa sổ.

  3. Chọn Google > Tạo Android App Bundle để tạo gói ứng dụng.

  4. (Không bắt buộc) Định cấu hình gói ứng dụng để hỗ trợ nhiều định dạng nén kết cấu.

Định cấu hình gói tài sản bằng API

Có thể định cấu hình phân phối nội dung qua tập lệnh trình chỉnh sửa. Tập lệnh này chạy như một phần của hệ thống xây dựng tự động.

Sử dụng lớp AssetPackConfig để xác định những tài sản cần đưa vào bản dựng Android App Bundle cũng như chế độ phân phối của tài sản đó. Các gói tài sản này không cần chứa 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);
}

Ngoài ra, bạn còn có thể sử dụng phương thức tĩnh BuildBundle trong lớp Bundletool để tạo Android App Bundle với gói tài sản, BuildPlayerOptionsAssetPackConfig.

Để tham khảo hướng dẫn từng bước, hãy xem nội dung Sử dụng Play Asset Delivery trong Lớp học lập trình trò chơi Unity.

Tích hợp với API Unity Play Asset Delivery

API Unity Play Asset Delivery cung cấp chức năng yêu cầu gói tài sản, quản lý tài nguyên tải xuống và truy cập tài sản. Trước tiên, hãy nhớ Thêm trình bổ trợ Unity vào dự án.

Hàm sử dụng trong API phụ thuộc vào cách bạn tạo các gói tài sản.

Nếu bạn đã sử dụng trình bổ trợ giao diện người dùng tạo gói tài sản, hãy chọn Gói tài sản được định cấu hình trình bổ trợ.

Nếu bạn đã dùng API (hoặc trình bổ trợ giao diện người dùng) để tạo gói tài sản, hãy chọn Gói tài sản được định cấu hình API.

Bạn triển khai API này theo loại hình phân phối của gói tài sản mà bạn muốn truy cập. Các bước này được thể hiện trong sơ đồ quy trình sau.

Sơ đồ quy trình gói tài sản cho trình bổ trợ

Hình 1. Sơ đồ quy trình truy cập gói tài sản

Truy xuất AssetBundle

Nhập thư viện Play Asset Delivery và gọi phương thức RetrieveAssetBundleAsync() để truy xuất 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);

Phân phối khi cài đặt

Các gói tài sản được định cấu hình là install-time sẽ có sẵn ngay khi khởi chạy ứng dụng. Bạn có thể sử dụng các nội dung sau để tải một cảnh trích từ 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]);

Phân phối tiếp nối nhanh và theo yêu cầu

Phần này áp dụng cho các gói tài sản fast-followon-demand.

Kiểm tra trạng thái

Mỗi gói tài sản được lưu trữ trong một thư mục riêng ở bộ nhớ trong của ứng dụng. Sử dụng phương thức isDownloaded() để xác định xem gói tài sản đã được tải xuống hay chưa.

Theo dõi việc tải xuống

Truy vấn đối tượng PlayAssetBundleRequest để theo dõi trạng thái của yêu cầu:

// 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.ShowCellularDataConfirmation dialog.
    default:
        break;
}

Tải xuống kích thước lớn

Các gói tài sản lớn hơn 150 MB có thể tự động tải xuống nhưng chỉ qua Wi-Fi. Nếu người dùng không sử dụng Wi-Fi, trạng thái PlayAssetBundleRequest sẽ được đặt thành AssetDeliveryStatus.WaitingForWifi và tải xuống sẽ bị tạm dừng. Trong trường hợp đó, hãy đợi đến khi thiết bị kết nối với Wi-Fi, tiếp tục tải xuống hoặc nhắc người dùng chấp thuận để tải gói xuống qua một kết nối di động.

if(bundleRequest.Status == AssetDeliveryStatus.WaitingForWifi) {
    var userConfirmationOperation = PlayAssetDelivery.ShowCellularDataConfirmation();
    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. In this case, we recommend
            // developers wait for Wi-Fi before attempting to download again.
            // You can get more info by calling GetError() on the operation.
        case ConfirmationDialogResult.Accepted:
            // User accepted the confirmation dialog - download will start
            // automatically (no action needed).
        case ConfirmationDialogResult.Declined:
            // User canceled or declined the dialog. Await Wi-Fi connection, or
            // re-prompt the user.
        default:
            break;
    }
}

Huỷ yêu cầu (chỉ theo yêu cầu)

Nếu bạn cần huỷ yêu cầu trước khi AssetBundles được tải vào bộ nhớ, hãy gọi phương thức AttemptCancel() trên đối tượng 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.
}

Yêu cầu gói tài sản theo cách không đồng bộ

Trong hầu hết trường hợp, bạn nên sử dụng Coroutine để yêu cầu gói tài sản theo cách không đồng bộ và theo dõi tiến trình như sau:

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;

Để biết thêm thông tin về cách xử lý lỗi, hãy xem danh sách AssetDeliveryErrorCodes.

Các phương thức Play Core API khác

Sau đây là một số phương thức API khác mà có thể bạn muốn sử dụng trong ứng dụng.

Kiểm tra kích thước tải xuống

Kiểm tra kích thước của AssetBundle bằng cách thực hiện lệnh gọi không đồng bộ đến Google Play và đặt phương thức gọi lại khi hoạt động hoàn tất:

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

Xoá AssetBundle

Bạn có thể xoá các AssetBundles theo dõi nhanh và theo yêu cầu hiện không tải trong bộ nhớ. Hãy thực hiện lệnh gọi không đồng bộ sau và đặt phương thức gọi lại khi hoàn tất:

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

Bước tiếp theo

Thử nghiệm việc phân phối tài sản trên thiết bị và trên Google Play.