Try   HackMD

Addressable 熱更新補充說明

熱更新,指的是不用重新安裝遊戲,只要打開遊戲就能更新資源,這代表遊戲要具備以下能力:

  1. 知道有哪些 Bundle 已被儲存在本地硬碟
  2. 知道有哪些 Bundle 被儲存在遠端可供下載
  3. 能在遊戲需要檢查更新時才主動比對上面兩者,知道是否有資源能被更新
  4. 確認有新版本後,只針對特定想更新的 Bundle 進行下載
  5. Bundle 下載至硬碟後、載入新資源進記憶體成為遊戲內容,完成熱更新

在 Addressable 的世界裡,上述的功能將如何達成?

打包更新資源

Addressable 的打包會產出四種檔案:

  1. addressables_content_state.bin
    這個檔案會出現在專案中的 Assets>AddressableAssetsData>Windows(平台)資料夾下。
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    此檔案主要保存 bundle 內容版本字串和位置訊息等資訊,讓你在更新 bundle 時,系統可以知道要去更新哪一份 bundle。
  2. catalog.hash
  3. catalog.json
  4. bundle
    另外還會在你所設定的打包路徑中產出內容目錄 catalog.json、hash 檔、和 bundle。
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

打包更新資源的方法如下圖所示,從 Addressable 介面的 Build 選擇 "Update a Previous Build",並且在 Build Data File 視窗中選擇 addressables_content_state.bin 檔案,按下開啟後,系統便會開始打包更新資源。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

打包結束後,觀察打包路徑中的檔案會發現增加了新的bundle。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我們也可以從內容目錄 catalog.json 中發現,material 資源包的檔案路徑從舊的 bundle 名稱變成了新的 bundle 名稱。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

這裡提到的 catalog 檔案就是遊戲用來比對本地與遠端的 Bundle 是否有差異的依據。

運行時檢查內容更新

用戶端運行時的更新通常包含三個步驟:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在b站上,Unity官方帳號發表的貼文中說明:

雖然每一步都提供了單獨的一套API可以使用,但如果直接使用後面的步驟,系統會自動幫你完成前面的步驟,例如你直接呼叫LoadAssetsAsync,系統會自動進行 catalog 的更新,並且下載對應的資源到本地快取中。

但為了避免直接使用 LoadAssetAsync 讓系統直接下載需要載入的資源,導致使用者流量爆炸,我們仍然會需要先告知使用者此次的更新需要下載的資源大小。

因此我們在判斷是否有新的資源要更新時,除了可以使用 CheckForCatalogUpdates 檢查 catalog 是否需要更新之外,也可以直接呼叫 GetDownloadSizeAsync 來取得新資源包的大小,如果數值大於零則表示有新的資源,我們可以透過這個數值告知使用者更新資源需要下載的資料量大小,若使用者同意,才進行後續的下載與載入。

其他補充

靜態資源包與動態資源包

在打包資源時,我們可以將資源分為兩類:

  • 靜態資源包 - 未來不會更新的資源包
  • 動態資源包 - 可能會平凡更新的資源包

區分它們的最主要目的是,我們希望靜態資源包可以一直存在於快取中,而動態資源包則會因為更新而整包重新下載並替換。

要將 bundle 設置為靜態,我們可以點選我們要設定的 Group,在 Inspector 介面中找到 Update Restriction,將它設定為"Cannot Change Post Release"。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

後續在 build bundle 時,可以先透過 Tool > Check For Content Update 來檢測這些靜態資源包有沒有做過修改,有做過修改則會告知你哪些資源有過修改,並讓你決定是否要將這些資源放到新的 Group 裡面;相反,動態資源包則設定為"Can Change Post Release"。
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我們也可以從產出的 bundle 來觀察,當你對靜態資源包的資源做修改,並且不將修改的內容抽出來而直接產 bundle 的話,你換看到舊版本的 bundle 直接被新版本覆蓋。

另一方面,你如果對動態資源包做修改,後續產 bundle 時,就會發現有新的 bundle 檔案生成,而 catalog 描述檔也會讓用戶端知道要載入新版本的 bundle。

Unique Bundle IDs Setting

在 Addressable 的設定檔當中,有一項設定叫 Unique Bundle IDs。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

當你在使用 Addressables.UpdateCatalogs 更新 catalog 檔案時,你可能會遇到 AssetBundle ID 衝突的問題,這時候你可以考慮開啟這項設定值。

然而,他同時也會產生如 build 速度變慢等問題,在使用他之前需要好好考慮,詳細資訊可參考官方說明