使用 Addressables 來管理資源
一、安裝
打開Package Manager,在Unity Technologies的目錄下找到Addressables,更新或下載,

二、配置
依次打開Windows/Asset Management/Addressables/Groups選單,
首次打開后會提示需要創建組態檔,點擊Create Addressables Settings,

Assets目錄下會生成AddressableAssetsData檔案夾,

Ⅰ. 認識資源組(AssetGroups)與組策略(AssetGroups Schemas)概念
-
點擊
Manage Groups,回傳剛才的Addressables Groups面板,此時已經有了兩個內置的組, -
Built In Data存盤的是工程中Resources檔案夾下的資源,隨App構建的場景資源,以及其他一些必要的資源等, -
Default Local Group (Default)組存盤的是工程中被標記為Addressables的資源,假如不對其進行手動分組,則默認放在這個組中, -
點擊
Create,可以指定模板來復制一個組或者創建一個全新的組,模板存盤在AddressableAssetsData/AssetGroupTemplates檔案夾下,默認有一個名為Packed Assets的模板,新創建的組存盤在AddressableAssetsData/AssetGroups檔案夾下,我們手動建立一個名為Remote的新組,

-
點擊
Remote組的Add Schema按鈕,添加Content Update Restriction和Content Packing & Loading策略,注意不要額外添加Resources and Built In Scene策略,這個已經由Built In Data組負責了,在
AssetGroups檔案夾中有一個Schemas檔案夾,存放著所有資源組的組策略序列化檔案,命名規則為$"{組名}_{策略型別}",

-
配置
Remote組策略,-
修改在
Content Update Restriction下的Update Restriction選項,Can Change Post Release的意思是,當前資源組進行最終構建時會完全覆寫上一次構建結果(打包出的檔案名與上一次不同,上一次的包徹底無效化,部署時可以直接刪掉),一般這種方式叫做 全量更新而
Can not Change Post Release則意味著,當前資源組構建時需要與上一次構建結果進行比對(Addressables Groups/Tools/Check for Content Update Restrictions),上一次構建出的包不發生變化,新構建的包則建立在舊包的基礎上(相同的資源存盤在舊包內,修改和添加的資源存盤在新包內,部署時需要將新包和舊包一起發到服務器上),這種方式一般叫做 增量更新, -
修改
Content Packing & Loading下的Build Path和Load Path選項,-
LocalBuildPath本地構建路徑,當App發布時,會將這個路徑下的包拷貝到App的StreamingAssets里, -
LocalLoadPath本地加載路徑,當App運行時,會從這個路徑下讀取資源包,一般也是在App的StreamingAssets里,Local___Path說明這個組中的資源包會包含在App的安裝包內,如果所有資源組都設定為Local,則這個App安裝包是 全資源包 (全資源包一般是設定為Can not Change Post Release的),
-
RemoteBuildPath遠程構建路徑,當構建資源包后,需要將這個路徑下的包拷貝到服務器上, -
RemoteLoadPath遠程加載路徑,當App運行時,會從這個地址下載catalog,并與本地catalog對比來判斷是否需要更新資源,
如果想對 全資源包 進行更新,可以點擊
Addressables Groups/Tools/Check for Content Update Restrictions,會自動生成差異化資源組,將這些資源組設定為遠程并構建部署,則可以將App內包含的舊資源進行覆寫, -
-
Advanced Options是更精細化控制資源包構建與加載流程的選項,無特殊情況保持默認即可,需要注意的是Include in Build選項,可以控制當前資源包是否參與本次構建,
-
Ⅱ. 總體配置
AddressableAssetSettings負責整體配置資源包的構建引數,
設定資源包地址的Profiles
Profiles/Profiles In Use 控制了當前資源包路徑設定,
我們剛才對資源包的路徑進行了本地與遠程的設定,但是并沒有深入了解這些路徑是如何拼接而成的,比如為什么本地資源包會在構建到StreamingAssets檔案夾中呢,

點擊Manage Profiles,彈出上圖的Addressables Profiles面板,之前我們設定的本地路徑與遠程路徑就是在這里定義的,總體上路徑由固定的字串、中括號與花括號組成,中括號內包含了發布時編輯器所確定下來的變數,比如運行平臺等;花括號則包含了App運行時所獲取的變數,也可以在代碼內手動指定一個自定義的變數,
這就解釋了為什么我們將資源包指定為Local___Path時,最侄訓存在于App的StreamingAssets檔案夾中,是因為[UnityEngine.AddressableAssets.Addressables.BuildPath]這個地址就是編輯器發布App時所指定目錄下的StreamingAssets檔案夾地址,而{UnityEngine.AddressableAssets.Addressables.RuntimePath}這個地址則是App運行時的StreamingAssets檔案夾地址,
我們也可以新建一個測驗用的Profile和一個發布用的Profile,只需要把RemoteLoadPath中的http地址指向測驗用服務器地址和正式版服務器地址即可,
設定是否需要遠程更新
假如我們的App不需要進行遠程資源加載和更新,則保持Content Updata/Build Remote Catalog不勾選即可,否則則需要將其勾選,

而Disable Catalog Update on Startup則決定是否在App啟動時自動更新catalog,
假如我們希望App啟動時將所有的更新包先行下載下來,則可以將其勾選,并在代碼中手動呼叫Addressables.InitializeAsync()、Addressables.CheckForCatalogUpdates()、Addressables.UpdateCatalogs()
等方法,獲取到需要更新的資源包串列,并對其依次進行手動更新,
假如我們希望在App運行中需要某個資源時才會去從遠程下載,則可以保持其不勾選的默認狀態,這種方式下Addressables系統會在App啟動時自動呼叫上述的一系列方法將本地catalog與遠程同步,但是并不會更新資源包,
三、資源管理
-
將資源匯入工程中
-
此時
Inspector面板上新添加了一個Addressable選項,
將需要打包的資源勾選,出現一長串的資源路徑,這個路徑就是我們加載這個資源時所需要的路徑引數 -
點擊
Select按鈕,彈出資源組面板,剛添加的資源會位于默認組員組Default Local Group (Default)中,

-
如果能保證不沖突的話,我們也可以將這個路徑手動簡化,或者讓編輯器自動對其進行簡化,在資源組面板右鍵資源并點擊
Simplify Addressable Names,可以將復雜的路徑簡化為不帶型別后綴的檔案名,方便使用,

-
也可以為資源指定標簽,將一系列資源指定為同一個標簽后,則可以在App運行時將其以按標簽加載的方式同時加載進來,比如我們將工程中的Lua腳本全部指定一個
Scripts的標簽等,
四、構建資源包
Ⅰ. 首次構建
首次構建資源包需要點擊資源組面板的Build/New Build/Default Build Script,

打包成功后在AddressableAssetsData檔案夾下生成一個保存當前資源狀態的bin檔案,這個檔案是后續資源增刪改時用來與前一次打包做對比用的,并且它保存了至關重要的catalog檔案資訊,
同時在RemoteBuildPath位置生成catalog以及遠程資源包,

此時我們可以隨即進行App的構建,
每次構建資源包,都需要重新構建App,
如果希望更新資源包,不能使用Build/New Build方式,
Ⅱ. 更新包
將資源增刪改完畢之后,點擊Tools/Check for Content Update Restrictions,

選擇首次構建時生成的bin檔案,彈出Content Update Preview面板,點擊Apply Changes,
我們這里的默認資源組的
Content Update Restriction選項設定的是Can not Change Post Release,因為本地資源已經跟隨App一同發布了,修改本地資源是沒有意義的,除非重新構建App,
編輯器替我們自動生成了新的遠程資源組,并將有變動的資源放了進去,
這里不要混淆 遠程資源組 和 Content Update Restriction 兩個概念,遠程資源組既可以標記為不可修改,也可以標記為可修改,
我們可以把這些資源放到其他遠程組里,也可以保持不變,這方面的策略應該顧及資源包的粒度,檔案大小等,嚴格執行起來還是比較燒腦的,
資源組重新設定完畢后,點擊Build/Update a Previous Build,并再次選擇首次構建時生成的bin檔案,以更新方式構建資源包,
切勿以
Build/New Build的方式構建,如果不小心點了,兩個解決方式,git reset --hard或者重新打包App……

此時打開遠程構建目錄(RemoteBuildPath),發現已經生成了由新的遠程資源組構建的資源包,而catalog檔案的修改日期也已經發生了變化,說明雖然catalog檔案名沒有發生變化,但是其內容已經更新了,
我這里截圖的catalog檔案名發生了變化,是寫文測驗的時候把之前的構建結果給刪了,實際上應該是不會發生變化的,請忽略,o_0

我們允許的流程是:構建資源包->構建App->以更新方式構建資源包->以更新方式構建資源包...
我們不允許的流程是:...->構建App->構建資源包...
原因是每次點擊Build/New Build/***,catalog檔案名都會發生變化,而App只記錄上一次構建資源包時的catalog檔案名,假如我們在構建App之后重新構建了資源包,則舊的App無法識別新的catalog,從而更新失敗,
五、部署
將RemoteBuildPath目錄下的檔案上傳至服務器,包括資源包以及catalog檔案,保證RemoteLoadPath可訪問即可,
實際部署還是比教程寫的要麻煩很多的,權限,跨域,負載能力,加密,防止各種網路攻擊等,各種手段都要用上,我們僅僅是驗證技術路線,麻煩事就先不考慮啦,
如果僅僅是測驗的話,其實編輯器還提供了一個Host功能

點擊Create/LocalHosting,新建一個服務端,指定埠,勾選Enable即可,
注意我們需要將
Profiles/RemoteLoadPath修改為http://本機IP或者localhost:埠號,默認Profiles的遠程加載地址多了一個[BuildTarget],這是訪問不到的,


六、加載
新建一個腳本,用來測驗資源的加載,
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;
public class SwitchSprites : MonoBehaviour
{
[SerializeField] private RawImage _emojiImage;
[SerializeField] private Text _infoText;
private int _indicator;
private AsyncOperationHandle<IList<Texture>> _operation;
private async void Start()
{
_operation = Addressables.LoadAssetsAsync<Texture>("emoji", null);
await _operation.Task;
_infoText.text = "Emoji Load Completed";
GetComponent<Button>().onClick.AddListener(() =>
{
_indicator++;
if (_indicator >= _operation.Result.Count)
{
_indicator = 0;
}
_emojiImage.texture = _operation.Result[_indicator];
});
}
private void OnDestroy()
{
Addressables.Release(_operation);
}
}
這里一上來直接就可以
Addressables.LoadAssetsAsync<Texture>(),是因為我測驗的時候沒有勾選AddressableAssetSettings/Content Update /Disable Catalog Update on Startup,所以App在加載時自動更新了catalog,而資源包下載則類似于Lazy 模式,即用即下載(快取中如果有匹配的資源包則直接加載),真正使用這套系統時,一般會采用勤快一點的模式,先更新必要的資源包,讀條一波,然后App才正式運行,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/378156.html
標籤:其他


