Addressable Asset System - thuốc "giảm cân" cho game của bạn ngay hôm nay (P1)

Tại sao phải dùng Addressable Asset System khi làm game?

weightloss-your-game.png Khi mới bắt đầu làm game, có một quan niệm vô cùng sai lầm mà chúng ta luôn gặp phải: "Game chỉ cần hay là người dùng sẽ chơi". Nhưng thế nào mới được gọi là "hay"? Thưởng thức một tựa game cũng giống như cách con người tiếp xúc một người bạn hoàn toàn mới vậy, rất phụ thuộc vào ấn tượng đầu tiên. Và một trong những yếu tố ảnh hưởng đến cảm xúc của người dùng nhất đó chính là dung lượng của game khi họ thấy trên App Store hoặc Google Play. Ví dụ như Candy Crush Saga thu hút hơn 1 tỉ download trên Google Play với dung lượng chỉ 74MB.
Ở những giai đoạn khởi đầu với một project, thường chúng ta sẽ tập trung vào game design để có những gameplay cuốn hút, tập trung vào đồ họa của các element trong game để thu hút người chơi. Vậy đâu còn thời gian để mà tính đến chuyện giảm size của file build nhỉ? Biết được những khó khăn đó của anh em developer, Unity đã cho ra mắt một package hoàn toàn free - thứ sẽ như một liều thuốc giảm cân hữu hiệu cho project đã lên tới hàng trăm MB của bạn - mang tên Addressable Asset System. unity.png

Addressable Asset System là gì?

Ý tưởng ban đầu

Okay nếu như bạn đã từng build project Unity của mình, bạn hẳn sẽ rõ được size của file build gồm từ 70% - 80% là từ các file resource (cụ thể ở đây là file hình ảnh). Vậy nếu không có chúng, game sẽ được downsize đáng kể rồi (^^)

Hmm mà khoan, nếu không có hình thì ông chơi game bằng trí tưởng tượng à?

Từ từ đã nào tôi đã nói xong đâu, bước tiếp theo sẽ là ném tất cả đống thứ nặng nề đó lên cloud, đợi đến khi người dùng chơi lần đầu thì script của chúng ta sẽ tự động tải đống resource đó xuống và gắn vào game. Về cơ bản flow của Addressable sẽ là


Đóng gói resource -> Ném lên cloud -> Build -> Tải resource -> Gắn vào game


Cách Addressable Asset System triển khai

Một số khái niệm cơ bản cần quan tâm

  • Built In Data : những asset sẽ được include trong file build, cụ thể là những asset thuộc đường dẫn */Resources/ hoặc những Scenes in Build
  • Group : nhóm những thứ cùng thuộc tính mà có thể đóng lại thành gói. Những thứ trong cùng 1 group sẽ được treat như nhau trong quá trình làm việc
  • Profile : setting chung cho các Addressable Group, dùng để setting link để get database từ cloud
  • Label : gắn nhãn cho riêng các object hoặc cả group để phân biệt
  • Tool : một số công cụ đặc biệt để xử lý khi làm việc với Addressable
  • Play mode : chỉ cần quan tâm tới 2 option. Use Asset Database để load thẳng từ database offline trong Unity và Use Existing Build để load từ cloud
  • Build : New Build để build bundle từ các group và Update a Previous Build để update các bản build cũ nếu có thay đổi

Đó là những khái niệm đơn giản nhất về Addressables, bạn có thể tìm hiểu kỹ hơn tại đây

Cách sử dụng Addressable Asset System

Bước 1: Install package Addressables

  1. Windows -> PackageManager
  2. Search Addressables
  3. Nhấn Install caidat-package.png

Bước 2: Tạo Addressable Group

  1. Windows -> Asset Management -> Addressables -> Group first-create-0.png
  2. Nhấn Create Addressables Setting first-create.png
  3. Tạo group mới bằng cách nhấn chuột phải -> Create New Group -> Packed Assets. Có thể rename lại thành bất cứ gì chúng ta muốn, miễn là 3, 4 tháng sau đọc lại vẫn hiểu được =))))) create-group.png

Bước 3: Addressable hóa project của bạn

  1. Kéo trực tiếp object bạn muốn Addressable vào Group, có thể là Scene, Prefab, Sprite... Ở đây mình kéo hẳn 1 scene vào luôn cho nó chất chơi. Lưu ý rằng khi bạn kéo cả scene vào Addressable Group thì tất cả các dependencies của scene đó (hình ảnh, âm thanh, prefabs...) cũng sẽ được Addressable và đóng gói chung bundle tạo ra của scene.
    add-to-group.png
  2. Khi trong tab Inspector của scene đó có tick Addressable thì bạn đã thành công tick.png

    Bước 4: Setting profile cho Addressable

  3. Mở tab Profile của Addressable open-profile-tab.png
  4. Ở tab Profile, tạo 1 profile mới Create -> New Profile
  5. Nhấn vào profile mới được tạo, dòng duy nhất cần quan tâm là Remote Load Path. Đây là nơi chứa đường dẫn cloud mà chúng ta sẽ định nghĩa để game load database xuống remoteloadpath.png
  6. Tạo 1 bucket để chứa database. Ở đây mình dùng Google Cloud Storage qua hướng dẫn
  7. Set Permission cho allUsers thành Storage Object Viewer. set-permission-cloud.png
  8. Sau khi setup cloud bucket xong, tạo 1 file bất kì rồi upload lên bucket, copy URL rồi paste ra sẽ thành một đường dẫn copyurl.png
  9. Chỉ copy phần trước tên file geturl.png
  10. Paste vào tab Profile của Addressables paste-to-profile.png
  11. Chọn Addressable group của bạn, đổi Load Path, Build Path thành RemoteLoadPath, RemoteBuildPath changetoremoteload.png
  12. Nhấn vào System Setting, thay đổi Profile In Use thành profile bạn tạo ra. Ngoài ra, enable Build Remote Catalog để có thể Update live content sau này

Bước 5: Build Addressable Bundle

Build bundle đầu tiên của bạn thôi nào ^^ build bundle.png Toàn bộ data được build ra sẽ nằm trong thư mục /ServerData/[BuildTarget]. Lưu ý, BuildTarget có thể tùy vào project mà là StandaloneWindows, Android hay iOS nhé finish build bundle.png Upload cả thư mục [BuildTarget], ở đây là StandaloneWindows lên bucket trên cloud upload.png

Bước 6: Viết script để load scene từ bundle trên database.

using System.Collections;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations; 

public class AddressableSceneManager : MonoBehaviour
{   
    public AssetReference MyScene;

    public void DownloadScene() 
    {
        StartCoroutine(downloadScene(MyScene));
    }

    private IEnumerator downloadScene(AssetReference scene) 
    {
        var currentDownloadScene = Addressables.LoadSceneAsync(scene, UnityEngine.SceneManagement.LoadSceneMode.Single);
        currentDownloadScene.Completed += SceneDownloadComplete;
        while (!currentDownloadScene.IsDone)
        {
            var status = currentDownloadScene.GetDownloadStatus();
            float progress = (int)(status.Percent * 100);
            Debug.Log("Downloading Scene: " + progress);
            yield return null;
        }
    }
    private void SceneDownloadComplete(AsyncOperationHandle<UnityEngine.ResourceManagement.ResourceProviders.SceneInstance> _handle) 
    {
        if (_handle.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log("Completed");
        }
        else if (_handle.Status == AsyncOperationStatus.Failed)
        {
            Debug.Log(_handle.OperationException);
        }
    }
}

Attach script vào 1 game object, assign MyScene là scene trước đó đã được addressable và gọi hàm DownloadMyScene() để test attach-scene-to-script.png Play rồi test thôi, nhớ đổi PlayMode thành Use Existing Build để load từ cloud nha ^^

LƯU Ý:

  • Khi build bạn không cần phải include scene đã được addressable vào build settings (vì sau này ta sẽ download nó từ cloud) để làm giảm dung lượng của file build nha!
  • Object được attach script trên bạn nên để nó DontDestroyOnLoad để sau này chuyển qua lại giữa các scene vẫn có thể dùng lại được

Như vậy là chúng ta đã xong phần build và load các bundle từ cloud với Addressable rồi đó. Hơi dài nhưng nhìn chung cũng đơn giản mà nhỉ? :))))))

Chúc các bạn thành công với hướng dẫn trên. Addressable tuy hơi phức tạp nhưng sẽ giúp bạn rất nhiều trong việc scale rộng project của mình ra trong tương lai đó ^^