AssetBundle trong Unity (phần 4)
Ở các bài lần trước, chúng ta đã tìm hiểu lý thuyết về AssetBundle trong Unity, đã đến lúc vận dụng chúng trong thực tế. Tổng quan Để sử dụng AssetBundle trong thực tế, chúng ta sẽ dùng AssetBundle Manager. AssetBundle Manager sẽ đảm nhiệm việc load AssetBundle và các thành phần liên quan ...
Ở các bài lần trước, chúng ta đã tìm hiểu lý thuyết về AssetBundle trong Unity, đã đến lúc vận dụng chúng trong thực tế.
-
Tổng quan
Để sử dụng AssetBundle trong thực tế, chúng ta sẽ dùng AssetBundle Manager. AssetBundle Manager sẽ đảm nhiệm việc load AssetBundle và các thành phần liên quan của chúng. Để load các Asset từ AssetBundle, chúng ta cần script sử dụng API từ AssetBundle Manager.
API của AssetBundle Manager bao gồm:
- Initialize() : khởi tạo đối tượng AssetBundle manifest.
- LoadAssetAsync() : load asset được đưa ra từ AssetBundle và xử lý tất cả các phụ thuộc.
- LoadLevelAsync() : load các scene được đưa ra từ AssetBundle và xử lý tất cả các phụ thuộc.
- LoadDependencies() : tải tất cả các gói asset cho một AssetBundle nhất đinh.
- BaseDownloadingURL : Thiết lập cơ sở tải url được sử dụng cho phụ thuộc tự động tải về.
- SimulateAssetBundleInEditor : set chế độ giả lập trong editor.
- Variants : sét các biến thể active.
- RemapVariantName() : giải quyết các AssetBundle đúng theo các biến thể active.
Trước hết, tạo 1 thư muc AssetBundle Sample với AssetBundle Manager. Có 3 scene ví dụ cơ bản trong thư mục "AssetBundleSample/Scenes":
- AssetLoader: chỉ ra cách để load một Asset bình thường từ AssetBundle.
- SceneLoader: chỉ ra cách để load một scene từ AssetBundle.
- VariantLoader: chỉ ra cách để load AssetBundle Variant.
Mỗi scene sẽ được điều khiển bởi một script rất đơn giản: LoadAssets.cs, LoadScenes.cs, LoadVariants.cs.
Để thử nghiệm thành công việc sử dụng các AssetBundle, có ba kịch bản có thể xảy ra.
Trong kịch bản đầu tiên, không sử dụng AssetBundle Manager, AssetBundles sẽ cần phải được xây dựng, triển khai và thử nghiệm với hệ thống hoàn chỉnh và chính thức tại chỗ. Trong kịch bản này, với mỗi thay đổi đến Asset trong project, AssetBundles mới cần được xây dựng và triển khai.
Có 2 cách để cải thiện workflow được cung cấp bởi AssetBundle Manager. Đó là Local AssetBundle Server và Simulation Mode.
Với Simulation Mode, AssetBundle Manager mô phỏng việc xây dựng AssetBundles khi chạy các dự án trong trình soạn thảo. Đây là quy trình làm việc nhanh nhất để sử dụng. Đơn giản chỉ cần kích hoạt tính năng "Simulation Mode" bằng cách sử dụng menu "Assets / AssetBundles / Simulation Mode" và thử nghiệm các dự án. Không AssetBundles nào sẽ được xây dựng. Điều quan trọng cần lưu ý là, mặc dù, AssetBundle Variant đó không làm việc với các Simulation Mode. Và cũng cần lưu ý rằng asset có thể được thao tác trong dự án khi Simulation Mode được kích hoạt, và ảnh hưởng của những thay đổi này có thể thấy trong các scene view, nơi sẽ không thể deploy với AssetBundles.
Các Local AssetBundle Server cung cấp một đại diện chính xác hơn về việc deploy AssetBundles, nhưng đòi hỏi rằng AssetBundles được xây dựng và được lưu trữ trong một thư mục mặc định trong dự án. Khi các Local AssetBundle Server được kích hoạt, những AssetBundles đã xây dựng sẽ có sẵn cho các editor và tất cả được xây dựng chạy cục bộ có thể đạt được Editor trên mạng nội bộ. Đây là cach duy nhất để test AssetBundle Variant ở local.
Để chạy một trong những sample scene, AssetBundle Manager phải được chạy ở một trong các chế độ trên. Để chạy các scene AssetBundle Variant , AssetBundles phải được xây dựng và Local AssetBundle Server phải được kích hoạt.
Trước hết, tải project sample tại đây: https://www.assetstore.unity3d.com/#!/content/45836.
-
Ví dụ 1: Loadding Assets
- Bật Simulation Mode
- Mở scene “AssetBundleSample/Scenes/AssetLoader”.
- Chú ý rằng scene cần trống, và chỉ chứa 1 Main Camera, Directional Light và “Loader” GameObject.
- Enter Playmode.
Viết 1 script LoadAssets.cs có địa chỉ “AssetBundleSample/Scripts/LoadAssets.cs”. Với 2 biến public string:
- assetBundleName: ghi tên của AssetBundle sẽ được load.
- assetName: ghi tên của Asset được load từ AssetBundle.
Script bao gồm một chức năng Start () và hai coroutines, gọi từ Start (). Trong Initialize (), DontDestroyOnLoad () được gọi, các đường dẫn đến các AssetBundles được thiết lập và AssetBundle Manifest được khởi tạo. Trong InstantiateGameObjectAsync () tên tài sản và AssetBundle được yêu cầu sử dụng AssetBundleManager.LoadAssetAsync () và nếu các tài sản được yêu cầu không phải là null, nó được khởi tạo.
Tạo một asset "MyCube" trong "AssetBundleSample / Asset" với Material tùy chọn với tên "MyMaterial", và 1 texture "UnityLogo". Ta sẽ có asset "MyCube" phụ thuộc vào "MyMatirual" và "UnityLogo". Chỉ có các asset "MyCube" đã được yêu cầu, và tất cả các asset phụ thuộc đã được nạp đúng.
Đặt vị trí cho AssetBundles trong Local AssetBundle Server khi scene đang chạy trong Editor hoặc từ một Development Build. Khi làm việc với Editor trong khi Simulation Mode được kích hoạt, AssetBundles sẽ được mô phỏng và thiết lập này sẽ không được sử dụng.
-
Ví dụ 2: Loading scenees
Bước đầu làm giống với ví dụ 1. Phần này sẽ được điều khiển bởi script LoadScenes.cs.
Và chúng ta cũng có 2 biến public kiểu String:
- sceneAssetBundle : tên của AssetBundle được load
- sceneName : tên của scene được load từ AssetBundle.
Script bao gồm một chức năng Start () và hai coroutines, gọi từ Start (). Trong Initialize (), DontDestroyOnLoad () được gọi, các đường dẫn đến các AssetBundles được thiết lập và AssetBundle Manifest được khởi tạo. Trong InitializeLevelAsync () tên Scene và isAdditive được sử dụng để yêu cầu một cảnh sử dụng AssetBundleManager.LoadLevelAsync (). Nếu scene yêu cầu là null, AssetBundle Manager sẽ hiển thị một lỗi trong giao diện console và kết thúc coroutine.
Điều quan trọng cần lưu ý ở đây, bằng cách nhìn vào asset "MyCube" trong "AssetBundleSample / Assets" là "Cube" là phụ thuộc vào "MyMaterial" mà sau đó phụ thuộc vào "UnityLogo". Chỉ có scene "TestScene" đã được yêu cầu. "Cube" được bao gồm trong "TestScene" và tất cả các tài sản phụ thuộc đã được nạp đúng bởi Manager AssetBundle.
-
Ví dụ 3: Variants
Để làm việc với AssetBundle Variants, các AssetBundles sẽ cần phải được build, như AssetBundle Variants không làm việc với Simulation Mode. Để xây dựng AssetBundles và biến thể của nó, chắc chắn rằng tất cả các asset được assign đúng với một Tên AssetBundle, nếu được sử dụng như một AssetBundle Variant, một AssetBundle cần phải được chỉ định tương ứng với Variant Name.
Một asset với cả AssetBundle Name và AssetBundle Variant Name được set.
Khi tất cả asset đã được assign cho một AssetBundle hoặc AssetBundle Vảiant, AssetBundle có thể được xây dựng bằng cách chọn "Assets / AssetBundle / Build AssetBundles".
Mặc định, các AssetBundle sẽ được tối ưu hóa cho việc xây dựng mục tiêu hiện tại và xây dựng thành một thư mục gọi là "AssetBundles" trong thư mục gốc của dự án, nhóm lại bằng cách build target.
Để dễ dàng trong công việc và sử dụng các AssetBundles mới được xây dựng mà không cần deploy, các Local AssetBundle Server cần được kích hoạt. Sử dụng “Assets/AssetBundles/Local AssetBundle Server” để kích hoạt Local AssetBundle Server.
Server local này nên chạy liền mạch, nhưng, như với bất kỳ giao tiếp mạng, server local sẽ có những hạn chế tương tự như bất kỳ network nào và có thể bị yêu cầu quyền truy cập, tường lửa, và những hạn chế khác. Hãy nhận biết rằng Local AssetBundle Server được cho phép một máy chủ AssetBundle local được thiết lập để các địa chỉ IP mặc định và Port, mà thường là http://192.168.1.115:7888/. Thông tin này được lưu trữ tạm thời trong file AssetBundleManager/Resources/AssetBundleServerURL. Thông tin này sẽ được set hoặc thay đổi tự động bởi AssetBundleManager, và không cần được chú ý bởi user.
Khi Local AssetBundle Server chạy, build AssetBundle có thể được test tại local:
- Bật Simulation Mode
- Enable Local AssetBundle Server bởi menu “Assets/AssetBundles/Local AssetBundle Server”.
- Mở scene “AssetBundleSample/Scenes/VariantLoader”.
- Chú ý rằng scene này là empty và chỉ cần chứa Main Camera, Directional Light và "Loader" GameObject.
- Chọn "Load SD".
- Chú ý rằng cube và một Sprite sẽ được load vào scene từ AssetBundle
- Thoát Playmode.
- Chọn Playmode.
- Chọn "Load HD".
- Lưu ý rằng các cube giống nhau và Sprite đã được nạp vào scene, nhưng các material, texture phụ thuộc của nó và texture Sprite đã được nạp từ một AssetBundle khác nhau. Các material có màu sắc khác nhau và những hình ảnh ở độ phân giải cao hơn đáng kể.
Scene này sẽ được điều khiển bởi “LoadVariants.cs”. Script này gần giống với "LoadScenes.cs". Sự khác biệt chính là biến xác định AssetBundle Variant để được nạp, và code để set các variant hoạt động. Có code bổ sung để tạo ra các UI button.
- public string variantSceneAssetBundle : tên của AssetBundle được load
- variantSceneName: tên của Scene được load từ AssetBundle
- private string[] activeVariants : mảng của các AssetBundleVariantName để xác định AssetBundle Variant được load
- private bool bundlesLoaded : dùng để ẩn Ui khi Asset đã load.
Script bao gồm một chức năng BeginExample () và hai coroutines, gọi từ Start (). BeginExample được gọi là do "Load HD" hoặc nút "Load SD" trong OnGUI. Trong Initialize (), DontDestroyOnLoad () được gọi, các đường dẫn đến các AssetBundles được thiết lập và AssetBundle Manifest được khởi tạo. Trong BeginExample (), giữa gọi Initialize () và InitializeLevelAsync (), các biến thể hoạt động được thiết lập. Các giá trị được thiết lập ở đây được tạo ra bởi các "Load HD" hoặc nút "Load SD" trong OnGUI. Trong InitializeLevelAsync () tên Scene và isAdditive được sử dụng để yêu cầu một scene sử dụng AssetBundleManager.LoadLevelAsync (). Nếu scebe yêu cầu là null, AssetBundle Manager sẽ hiển thị một lỗi trong giao console và kết thúc coroutine.