Sử dụng gói tài sản trong Unity

Unity có nhiều tính năng hữu ích, một trong số đó là hỗ trợ Asset Bundles.

Gói tài sản là gì?

Gói nội dung là các tệp chứa nội dung trò chơi, từ nội dung đơn giản như mô hình 3D, kết cấu và clip âm thanh đến những nội dung phức tạp hơn, chẳng hạn như Cảnh và Prefabs.

Tuy nhiên, tập lệnh không thể được đưa vào Gói nội dung mà chỉ có các tham chiếu của chúng, vì vậy hãy cẩn thận khi đổi tên hoặc di chuyển chúng vì nó sẽ ngắt kết nối và bạn sẽ cần phải xây dựng lại Gói nội dung để chúng hoạt động trở lại.

Khi nào nên sử dụng Gói tài sản?

Sử dụng Gói tài sản khi trò chơi của bạn có nhiều tài sản và việc đưa chúng vào bản dựng sẽ ảnh hưởng đến thời gian tải xuống ban đầu.

Xuất gói tài sản

Việc xuất Gói tài sản được thực hiện theo hai bước: gán tên Gói tài sản và xây dựng chúng bằng Trình chỉnh sửa script.

Gán tên gói tài sản

Để gán tên Gói nội dung, hãy chọn nội dung trong chế độ xem Dự án (đây có thể là Prefab, Kết cấu hoặc thậm chí là Cảnh), sau đó trong chế độ xem Thanh tra ở dưới cùng, hãy nhấp vào menu thả xuống, sau đó nhấp vào 'New...' (hoặc nhấp vào tên Gói tài sản hiện có).

Việc chỉ định cùng một tên gói cho nhiều nội dung sẽ gộp chúng lại với nhau trong cùng một Gói nội dung. Bạn nên đóng gói Cảnh riêng biệt với phần nội dung còn lại.

Ngoài ra, bạn không phải chỉ định tên Gói nội dung cho mọi nội dung. Thông thường, bạn chỉ cần gán tên gói cho nhà lắp ghép hoặc nội dung chính, phần phụ thuộc còn lại sẽ tự động được đưa vào.

Gói tài sản xây dựng

Để xây dựng Gói tài sản, hãy làm theo các bước dưới đây:

  • Tạo một thư mục mới có tên Editor (nếu bạn chưa có)
  • Tạo một tập lệnh mới bên trong thư mục Editor, đặt tên là BuildAssetBundles rồi dán đoạn mã bên dưới vào bên trong nó:

BuildAssetBundles.cs

using UnityEngine;
using UnityEditor;

public class BuildAssetBundles
{
    [MenuItem("Build/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string outputFolder = "Assets/__Bundles";

        //Check if __Bundles folder exist
        if (!AssetDatabase.IsValidFolder(outputFolder))
        {
            Debug.Log("Folder '__Bundles' does not exist, creating new folder");

            AssetDatabase.CreateFolder("Assets", "__Bundles");
        }

        BuildPipeline.BuildAssetBundles(outputFolder, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
    }
}

Sau khi lưu, bạn sẽ thấy nó sẽ thêm một nút menu (Build -> Build AssetBundles). Nhấp vào nó sẽ xây dựng Gói tài sản và đặt chúng vào thư mục "__Bundles".

Đang tải gói tài sản

Để tải Gói tài sản, trước tiên nó cần được tải xuống bằng cách sử dụng UnityWebRequest và sau đó giải nén bằng một chức năng đặc biệt. Nói chung, có 2 loại Gói nội dung, loại chứa nội dung và loại chứa Cảnh.

Đang tải tài sản từ gói tài sản

Đoạn mã bên dưới tải xuống Gói tài sản có tên "fpsplayer" sau đó trích xuất Prefab có tên "FPSPlayer" và khởi tạo nó trong Cảnh:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "fpsplayer"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Extract Prefab named "FPSPlayer" from the Asset Bundle
                GameObject playerPrefab = assetBundle.LoadAsset("FPSPlayer") as GameObject;
                // Instantiate Player Prefab
                Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
                // Unload Asset Bundle from memory (but do not destroy the existing instance(s))
                assetBundle.Unload(false);
            }
        }

Đang tải cảnh từ gói tài sản

Việc tải Cảnh từ Gói tài sản được thực hiện hơi khác một chút.

Mã bên dưới sẽ tải xuống Gói tài sản có Cảnh và sẽ sẵn sàng để tải:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "testscene"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle (This will make the Scene available for load)
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Load the Scene extracted from the Asset Bundle
                UnityEngine.SceneManagement.SceneManager.LoadScene("TestScene");
            }
        }