Khi tích hợp tính năng phân phối thành phần, trò chơi Unity có thể truy cập vào các gói thành phần bằng cách sử dụng Addressable hoặc AssetBundle. Addressable là giải pháp phân phối thành phầ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 thành phầ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 thành phần trên Android. Unity cung cấp Play Asset Delivery (PAD) API để xử lý các gói thành phần Android bằng Addressable. Để biết thông tin về cách sử dụng Addressable, hãy xem:
- Gói Addressable dành cho Android
- Hướng dẫn về PAD (Play Asset Delivery) cho Unity
- Tài liệu tham khảo về PAD API cho Unity
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 thành phần trên Android. Các tệp AssetBundle chứa thành phần nối tiếp được tải bằng công cụ Unity khi ứng dụng đang chạy. Các tệp này dành riêng cho 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 thành phần. Trường hợp phổ biến nhất là một tệp AssetBundle được đóng gói thành gói thành phầ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 thành phần, hãy định cấu hình gói thành phầ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 thành phần.
Điều kiện tiên quyết
- Thiết lập môi trường phát triển:
OpenUPM-CLI
Nếu đã cài đặt OpenUPM CLI, bạn có thể cài đặt sổ đăng ký OpenUPM bằng lệnh sau:
openupm add com.google.play.assetdelivery
OpenUPM
Mở chế độ cài đặt trình quản lý gói bằng cách chọn tuỳ chọn trình đơn Unity Edit > Project Settings > Package Manager (Chỉnh sửa > Cài đặt dự án > Trình quản lý gói).
Thêm OpenUPM làm sổ đăng ký có giới hạn vào cửa sổ Trình quản lý gói:
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
Mở trình đơn trình quản lý gói bằng cách chọn tuỳ chọn trình đơn Unity Window > Package Manager (Cửa sổ > Trình quản lý gói).
Đặt trình đơn thả xuống phạm vi người quản lý để chọn Registries của tôi.
Chọn gói Trình bổ trợ Tính toàn vẹn của Google Play cho Unity trong danh sách gói rồi nhấn Install (Cài đặt).
Nhập từ GitHub
Tải bản phát hành
.unitypackage
mới nhất xuống từ GitHub.Nhập tệp
.unitypackage
bằng cách chọn tuỳ chọn trình đơn Unity Assets > Import package > Custom Package (Tài sản > Nhập gói > Gói tuỳ chỉnh) rồi nhập tất cả các mục.
Sử dụng giao diện người dùng để định cấu hình AssetBundle
Định cấu hình từng AssetBundle trong gói thành phần:
- Chọn Google > Android App Bundle > Cài đặt phân phối nội dung.
- Để chọn thư mục chứa trực tiếp tệp AssetBundle, nhấp vào Thêm thư mục.
Đố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ổ.
Chọn Google > Tạo Android App Bundle để tạo gói ứng dụng.
(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 thành phầ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 thành phần cần đưa vào bản dựng Android App Bundle cũng như chế độ phân phối của thành phần đó. Các gói thành phầ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 thành phần, BuildPlayerOptions và AssetPackConfig
.
Để 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 thành phần, quản lý tài nguyên tải xuống và truy cập thành phầ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 tuỳ thuộc vào cách bạn tạo các gói thành phần.
Nếu bạn đã sử dụng trình bổ trợ giao diện người dùng tạo gói thành phần, hãy chọn Gói thành phầ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 thành phần, hãy chọn Gói thành phần được định cấu hình API.
API tương tự nhau bất kể bạn muốn truy cập loại phân phối nào của gói thành phần. Các bước này được thể hiện trong sơ đồ quy trình sau đây.
Truy xuất gói thành phần
Nhập thư viện Play Asset Delivery và gọi phương thức RetrieveAssetPackAsync()
để tải gói thành phần xuống nếu phiên bản mới nhất chưa có sẵn trên đĩa.
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);
Phân phối khi cài đặt
Một gói thành phần được định cấu hình install-time
sẽ có sẵn ngay khi khởi chạy ứng dụng, nhưng cần tải thành phần của gói đó vào bộ nhớ. Xem Tải thành phần vào bộ nhớ.
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 thành phần fast-follow
và on-demand
.
Kiểm tra trạng thái
Mỗi gói thành phầ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 isDone()
để xác định xem gói nội dung đã được tải xuống và có sẵn chưa hay đã xảy ra lỗi.
Theo dõi việc tải xuống
Truy vấn đối tượng PlayAssetPackRequest
để 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 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;
Tài nguyên tải xuống kích thước lớn
Các gói tài sản lớn hơn 200 MB có thể tự động tải xuống, nhưng chỉ khi thiết bị được kết nối với Wi-Fi. Nếu người dùng không sử dụng Wi-Fi, trạng thái PlayAssetPackRequest
được đặt là AssetDeliveryStatus.WaitingForWifi
và tệp 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.
Yêu cầu người dùng xác nhận
Nếu một gói có trạng thái AssetDeliveryStatus.RequiresUserConfirmation
, thì quá trình tải xuống sẽ không tiếp tục cho đến khi người dùng chấp nhận hộp thoại hiển thị với PlayAssetDelivery.ShowConfirmationDialog()
. Trạng thái này có thể xảy ra nếu Play không nhận dạng được ứng dụng. Lưu ý rằng việc gọi PlayAssetDelivery.ShowConfirmationDialog()
trong trường hợp này sẽ khiến ứng dụng được cập nhật. Sau khi cập nhật, hãy yêu cầu lại các tài sản.
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; } }
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 tải các gói thành phần xuống, hãy gọi phương thức AttemptCancel()
trên đối tượng 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. }
Tải thành phần vào bộ nhớ
Sau khi yêu cầu hoàn tất, sử dụng một trong các hàm sau để tải nội dung vào bộ nhớ:
- Sử dụng
PlayAssetPackRequest.GetAssetLocation()
để tải đối tượngAssetLocation
. Đối tượng này cung cấp đường dẫn, độ lệch và kích thước của thành phần để có thể tải được qua ổ đĩa. - Nếu thành phần là một AssetBundle, bạn có thể sử dụng phương thức
PlayAssetPackRequest.LoadAssetBundleAsync(assetPath)
tiện lợi. Đường dẫn thành phần mà bạn truyền vào phải tương ứng với đường dẫn đến AssetBundle bên trong gói thành phần. Thao tác này sẽ trả về AssetBundleCreateRequest.
Yêu cầu gói thành phầ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 thành phần theo cách không đồng bộ và theo dõi tiến trình như sau:
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;
Để biết thêm thông tin về cách xử lý lỗi, hãy xem danh sách mã lỗi.
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.
Truy xuất nhiều gói thành phần
Để truy xuất nhiều gói thành phần cùng lúc, hãy sử dụng chức năng sau:
// assetPackNames is an array of strings corresponding to asset packs. PlayAssetPackBatchRequest batchRequest = PlayAssetDelivery.RetrieveAssetPackBatchAsync(<IListstring> assetPackNames);
Theo dõi trạng thái của từng yêu cầu bằng cách kiểm tra Dictionary
tiểu bang:
// 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;
Kiểm tra kích thước tải xuống
Kiểm tra kích thước một gói thành phần bằng cách thực hiện lệnh gọi không đồng bộ đến Google Play và thiết lập phương thức gọi lại khi thao tác này 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á gói thành phần theo dõi nhanh và theo yêu cầu hiện chưa tải vào 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. } };
Các bước tiếp theo
Thử nghiệm việc phân phối thành phần trên thiết bị và trên Google Play.