記錄一下Addressable
參考文章 :addressable介紹
B站有個官方視頻 講解的不錯
視頻講解
Addressable的資源更新好像更優(yōu)化一點,即使一個大包更新也只會更新變化過的內(nèi)容,把大包拆散。不是整個AB包更新 所以原來很注意的打包力度和劃分規(guī)則就沒太大的必要了是么?好像這樣還不確定。他會把所有的多次依賴放一個大包,這個大包還可以拆分下載!
相關(guān)概念 名稱
1.Address:便于運行時索引的Asset位置標識符。
2.AddressableAssetData目錄:存儲你工程里所有Addressable Asset的元數(shù)據(jù)。位置在工程的Assets目錄。
3.Asset group:一組可以在構(gòu)建時處理的Addressable Assets.
4.Asset group schema:定義一組數(shù)據(jù),這些數(shù)據(jù)可以在生成期間分配給Group并使用。
5.AssetReference:類似于直接引用但會延遲初始化的對象。AssetReference對象將GUID存儲為可以按需加載的Addressable的GUID。
6.Asynchronous loading:允許在開發(fā)過程中更改asset 及其依賴項的位置,而無需修改游戲代碼。異步加載是Addressable Asset System的基礎(chǔ)實現(xiàn)。
6.Build script:運行asset group處理器來打包assets,并為資源管理器提供地址和資源位置之間的映射。
7.Label:提供用于運行時加載類似項的附加 Addressable Asset標識符。比如(Addressables.DownloadDependenciesAsync("spaceHazards");)。
可以手動標記資源可以尋址,當(dāng)然正常還是代碼來操作
這個方便的是 在編輯器模式下 就可以模擬打包出來的版本,不用真的完整打包。 還能分析依賴,和更新的東西。節(jié)省了不少工作
在加載Asset時,
要用到在打包時定義的string 類型地址,兩個接口都是異步
UnityEngine.AddressableAssets命名空間下的下列方法:
Addressables.LoadAssetAsync ("AssetAddress");這個加載指定地址的asset。
Addressables.InstantiateAsync("AssetAddress");這個實例化指定地址的asset,并且添加到場景中

加載sub-assets
- Components :目前還不能通過Addressable直接加載GameObject的Components。必須加載或?qū)嵗疓ameObject,然后從其中查找組件引用。要了解如何擴展Addressable以支持組件加載,可以參閱ComponentReference示例。
- Sub-assets:這套系統(tǒng)支持加載Sub-assets,但需要特殊的語法。Sub-assets的例子包括sprite sheet中的sprite ,或者FBX文件中的animation clips等。有關(guān)直接加載sprites的示例,可以參考sprite加載示例。
從asset里加載sub-objects可以使用下面的API:
Addressables.LoadAssetAsync <IList >("MySpriteSheetAddress");
如果加載單個的sub-objects,可以使用:
Addressables.LoadAssetAsync ("MySpriteSheetAddress[MySpriteName]");
assets中可用的名稱可以在主Addressables group編輯器窗口中查看。此外,還可以使用AssetReference訪問assets的子對象。
還可以在界面直接拖 AssetReference 類似原來的Gameobject 不過我覺得不太實用。加載的接口也是兩個異步接口:
代碼中的 聲明方式:public AssetReference 變量
AssetRefMember.LoadAssetAsync ();
或者
AssetRefMember.InstantiateAsync(pos, rot);
說說實際使用的情況
原來的AB規(guī)則 在第一次打開Groups窗口時有提示,可以一次性導(dǎo)入。
Addressable Assets開發(fā)周期
asset管理
可以給asset綁定一個地址,代碼根據(jù)這個地址來加載。不用關(guān)注它的位置,目錄等。直接用地址加載這個很爽。少寫很多代碼。
Asset Group Schemas
Schemas 定義一組數(shù)據(jù),可以在inspector 上把Schemas綁定到一個AssetGroup上。 這個目前不太明白用途
腳本構(gòu)建
要實現(xiàn)自己的Group規(guī)則,需要繼續(xù)IDataBuilder接口的ScriptableObject assets
Play Mode Scripts
Use Asset Database faster
沒啥好說字面意思 Asset DataBase 加載Asset
Simulate Group(advanced)
在不創(chuàng)建AB的情況下 來模擬AB的加載流程,分析布局和依賴,。Asset通過ResourceManager從assetDataBase加載,就假裝它們是通過包加載的一樣。若要查看游戲期間Bundles加載或卸載的時間,請在Addressables事件查看器窗口(Window>Asset Management>Addressable>Event Viewer)中查看Asset使用情況。Simulate Groups mode可以幫助您模擬加載策略,并調(diào)整內(nèi)容Groups以找到生產(chǎn)和發(fā)行版的適當(dāng)平衡
** Use Existing **
近乎 真正的發(fā)布版本,很多團隊喜歡使用這種應(yīng)該。必須通過選擇Build>New Build>Default Build Script,或者在游戲腳本中使用AddressableAssetSettings.BuildPlayerContent()方法,在Addressables組窗口(Window>Asset Management>Addressable>group>group)中構(gòu)建此模式的內(nèi)容。
內(nèi)容更新
先本地檢查什么內(nèi)容需要更新 Check命令 ,然后在Update
如果已經(jīng)修改了任何StaticContent組中的assets,則需要運行“Check for Content Update Restrictions”命令。這將從靜態(tài)組中得到任何修改后的asset,并將其移動到一個新Groups中。生成新的Asset Groups:
1、打開Unity的Addressables Groups窗口。(Window > Asset Management > Addressables > Groups)
2、Addressables Groups窗口上選擇菜單Tools,然后點擊Check for Content Update Restrictions。
3、在打開的BuildDataFile對話框中,選擇addressables_content_state.bin文件(默認情況下,該文件位于Asset/AddressableAssetsData Project目錄中。
此數(shù)據(jù)用于確定自上次構(gòu)建應(yīng)用程序以來有哪些Assets或依賴項已被修改。為了準備更新內(nèi)容的生成,系統(tǒng)將將這些Assets移動到一個新的Group中。
注意:如果您的所有更改僅限于non-static groups,則此命令將不起任何作用
重要:在開始prepare operation之前,Unity建議你使用版本控制系統(tǒng)打個分支,并在分支上進行操作。prepare operation會以適合的updating content的方式對Asset Groups進行重新排列。分支會確保下次再發(fā)布一個新player時,可以快速回滾到你自定義的設(shè)定。
構(gòu)建更新 發(fā)布更新
1.還是打開Groups窗口
2.Build->Update a previous Build
3.對話窗口 選擇上次打包的構(gòu)建目錄,必現(xiàn)要包含一個contain an addressables_content_state.bin 文件 上一步check時候生成的
構(gòu)建會生成一個內(nèi)容目錄、一個Hash文件和asset bundles。
生成的內(nèi)容目錄具有與選定應(yīng)用程序生成中的目錄相同的名稱,并且會覆蓋舊目錄和hash文件。應(yīng)用程序會加載hash文件來確定新目錄是否可用。系統(tǒng)從應(yīng)用程序附帶的或已經(jīng)下載的現(xiàn)有AssetBundles中加載未經(jīng)修改的Assets。
系統(tǒng)使用addressables_content_state.bin文件中的內(nèi)容、版本、字符串和位置信息來創(chuàng)建AssetBundles。不包含更新內(nèi)容的AssetBundles的文件名和原來的一樣。如果AssetBundles包含更新的內(nèi)容,則生成包含更新內(nèi)容的新AssetBundles,該包會具有新的文件名,以便與原始文件共存。帶有新文件名的AssetBundles必須復(fù)制到指定的內(nèi)容托管位置。
系統(tǒng)還可以為靜態(tài)內(nèi)容構(gòu)建AssetBundles,但是并不需要將它們上傳到內(nèi)容托管位置,因為沒有Addressableasset entries引用它們。
構(gòu)建
·用窗口構(gòu)建, Groups窗口 選Build update a Previous Build
·在Build Data File 對話框打開的時候,選擇一個已經(jīng)存在的APP構(gòu)建的構(gòu)建目錄,這個目錄下必須要包含contain an addressables_content_state.bin 文件。
系統(tǒng)使用addressables_content_state.bin文件中的內(nèi)容、版本、字符串和位置信息來創(chuàng)建AssetBundles。帶有新文件名的AssetBundles必須復(fù)制到指定的內(nèi)容托管位置。(就是固定路徑的下載位置)
確定一下 Remote——static 和 Remote_NonStatic 的具體含義和區(qū)別
感覺這個更新有點問題,非靜態(tài)Bundle會下載一些多余數(shù)據(jù)
注意,上面的示例具有以下意義:
1、任何更改后的本地Assets都會永久殘存在在用戶的設(shè)備上。并且保持未使用狀態(tài)。
2、如果用戶已經(jīng)緩存了一個非靜態(tài)Bundle,他們將需要重新下載包,包括未更改的Assets(例如,AssetY和Assetz)。理想情況下,用戶沒有緩存Bundle,在這種情況下,他們只需要下載新的Remote_non-Static包。
3、如果用戶已經(jīng)緩存了Static_Remote bundle,他們只需要下載更新的Asset(在本例中,通過content_update_group下載AssetL)。但這種情況是很理想的。如果用戶沒有緩存過Bundle,則必須通過content_update_group下載新的AssetL,并通過未引用的Remote_Static bundle下載現(xiàn)已失效的AssetL。不管初始的緩存狀態(tài)如何,在完成的某個時候,用戶都會在他們的設(shè)備上擁有已停用的AssetL,盡管從未被訪問或者引用過,但卻會被永久的緩存。
Assets 托管服務(wù)
這個直接把資源打到服務(wù)器,大家更新配置就可以在線使用資源。算是遠程工作的利器吧,但一般的項目組應(yīng)該不敢這么干。而且受網(wǎng)絡(luò)限制比較多,不如本地穩(wěn)定,好處是可以資源一直最新,本地存儲占用少。速度快點?也是模擬真實環(huán)境一個不錯的思考。不過感覺沒太大必要
真的要用再返回來看吧
Addressable Assets 內(nèi)存管理
這里加載等返回的變成了句柄,不再強行管理實際asset。直接操作句柄加載釋放資源
在所有情況下,釋放方法都可以接受加載的Asset,也可以接受Load返回的操作句柄。例如,在場景創(chuàng)建期間(下面描述),Load返回一個AsyncOperationHandle ,您可以通過這個返回的句柄或通過保持句柄同步釋放AsyncOperationHandle 。
Asset加載
*原來的引用計數(shù)和管理回調(diào)都可以交給addressables *
要加載Asset,請使用Addressables.LoadAssetAsync或Addressables.LoadAssetsAsync。
這會將Asset加載到內(nèi)存中,而不會實例化它。每次加載調(diào)用執(zhí)行時,它都會為每個加載的asset添加一個引用計數(shù)。如果您使用相同的地址三次調(diào)用LoadAssetAsync,您將得到AsyncOperationHandle結(jié)構(gòu)的三個不同實例,所有這些實例都引用相同的底層操作。對于相應(yīng)的Asset,該操作的引用計數(shù)為3。如果加載成功,則生成的AsyncOperationHandle結(jié)構(gòu)將包含.Result屬性中的asset。您可以使用Unity的內(nèi)置實例化方法使用加載的Asset來實例化,這不會增加Addressable的引用計數(shù)。
若要卸載Asset,請使用Addressables.Releases方法,該方法將減少ref計數(shù)。當(dāng)給定Asset的引用計數(shù)為零時,該Asset就會被卸載,并減少任何依賴項的引用計數(shù)。
Scene 加載
要加載場景,請使用Addressables.LoadSceneAsync。您可以使用此方法以Single模式加載場景,這將關(guān)閉所有打開的場景,或以Additive模式加載場景,有關(guān)詳細信息,請參閱場景模式加載的文檔。
若要卸載場景,請使用Addressables.UnloadSceneAsync,或在Single模式下打開新場景。您可以使用Addressables接口或使用SceneManager.LoadScene或SceneManager.LoadSceneAsync方法打開一個新場景。打開一個新場景將關(guān)閉當(dāng)前場景,并適當(dāng)?shù)販p少引用計數(shù)。
GameObject 實例化
原來的 實例化可以用,但是沒法計數(shù),用他們的最省心,這段比較關(guān)鍵,保證一個合理的內(nèi)存優(yōu)化
要加載和實例化GameObject asset,請使用Addressables.InstantiateAsync。這將實例化由指定地址參數(shù)定位的Prefab。Addressable系統(tǒng)將加載Prefab及其依賴項,增加所有相關(guān)Asset的引用數(shù)。
在同一個地址上三次調(diào)用InstantiateAsync將導(dǎo)致所有相關(guān)Asset的引用數(shù)為3。但是,與三次調(diào)用LoadAssetAsync不同,每個InstantiateAsync調(diào)用都返回指向唯一操作的AsyncOperationHandle。這是因為每個InstantiateAsync的結(jié)果都是唯一的實例。InstantiateAsync和其他Load調(diào)用之間的另一個區(qū)別是可選的trackHandle參數(shù)。當(dāng)設(shè)置為false時,必須在釋放實例時保留要使用的AsyncOperationHandle。這更有效率,但需要更多的開發(fā)精力。
若要銷毀實例化的GameObject,請使用Addressables.ReleaseInstance,或關(guān)閉包含實例化對象的場景。這個場景可以是加載(從而關(guān)閉)在Additive模式或Single模式。這個場景也可以使用Addressable或SceneManagementAPI加載。如上所述,如果將trackHandle設(shè)置為false,則只能使用句柄調(diào)用Addressables.ReleaseInstance,而不能使用實際的GameObject調(diào)用。
注意:如果在未使用Addressables API創(chuàng)建的實例上調(diào)用Addressables.ReleaseInstance,或使用trackHandle==false創(chuàng)建的實例,則系統(tǒng)將檢測到該實例并返回false,以指示該方法無法釋放指定的實例。在這種情況下,實例不會被銷毀。
InstantiateAsync有一些相關(guān)的開銷,因此如果你需要每幀實例化相同的對象數(shù)百次,可以考慮通過Addressables API加載,然后通過其他方法實例化。在本例中,可以調(diào)用Addressables.LoadAssetAsync,然后保存結(jié)果并為該結(jié)果調(diào)用GameObject.Instantiate()。這允許靈活地以同步方式調(diào)用實例化。缺點是Addressable系統(tǒng)不知道你創(chuàng)建了多少實例,如果管理不當(dāng),可能會導(dǎo)致內(nèi)存問題。例如,引用紋理的Prefab將不再具有要引用的有效加載紋理,從而導(dǎo)致BUG出現(xiàn)(或閃退)。這些問題很難跟蹤,因為你可能不會立即觸發(fā)內(nèi)存GC(請參閱下面關(guān)于清除內(nèi)存的部分)。
Data加載
Data loading不需要它們的AsyncOperationHandle.Result發(fā)布的接口,仍然需要釋放操作本身。例如Addressables.LoadResourceLocationsAsync和Addressables.GetDownloadSizeAsync。它們加載你可以訪問的數(shù)據(jù),直到釋放操作為止。這個版本可以通過Addressables.Releases完成。
后臺交互
在AsyncOperationHandle.Result字段中不返回任何內(nèi)容的操作具有一個可選參數(shù),可在完成時自動釋放操作句柄。如果在這些操作句柄完成后不再需要其中一個操作句柄,請將autoReleaseHandle參數(shù)設(shè)置為true,以確保清除操作句柄。你希望autoReleaseHandle為false的場景是,你需要在操作句柄完成后檢查它的狀態(tài)。這些接口的例子是Addressables.DownloadDependenciesAsync和Addressables.UnloadScene。
addressable 事件器
這是個好東西,實時看到資源引用和加載計數(shù)的情況
使用Addressables Event Viewer窗口監(jiān)視所有Addressable system 操作的ref計數(shù)。要訪問編輯器中的窗口,請選擇Window>AssetManagement>Addressables>Event Viewer。

·白色垂直行指示發(fā)生加載請求的幀。
·藍色背景表示當(dāng)前已加載的asset。
·圖的綠色部分表示asset的當(dāng)前參考計數(shù)。
AsyncOperationHandle 句柄分析
Addressables API中的幾個方法都會返回AsyncOperationHandle結(jié)構(gòu)。此句柄的主要目的是允許訪問操作的狀態(tài)和結(jié)果。操作的結(jié)果在調(diào)用Addressables.Relace或Addressables.ReleaseInstance之前回保持有效。
當(dāng)操作完成時,AsyncOperationHandle.Status屬性要么是AsyncOperationStatus.Succeeded ,要么是AsyncOperationStatus.Failed。如果成功,可以通過AsyncOperationHandle.Result屬性訪問結(jié)果。
你可以定期檢查操作狀態(tài),也可以使用AsyncOperationHandle.Complete事件注冊已完成的回調(diào)。當(dāng)不再需要返回的AsyncOperationHandle結(jié)構(gòu)提供的assets時,應(yīng)該使用Addressables.Releases方法來釋放它。
使用AsyncOperationHandle.Completed回調(diào)為完成事件注冊偵聽器:

AsyncOperationHandle實現(xiàn)了IEnumerator,因此可以在coroutines中生成:

Addressable還通過AsyncOperationHandle.Task屬性支持異步await :

Addressables分析器
正常的使用沒什么可說的,主要是自定義規(guī)則 的需求
AnalyzeRule objects
創(chuàng)建一個AnalyzeRule類的子類,重寫以下屬性:
CanFix: 告訴分析規(guī)則是否被認為是可修正的。
ruleName 分析窗口上用來展示規(guī)則的名字。
你還需要重寫以下方法,具體如下:
List RefreshAnalysis(AddressableAssetSettings settings)
void FixIssues(AddressableAssetSettings settings)
void ClearAnalysis()注意:如果您的規(guī)則被指定為不可修復(fù),則不必重寫FixIssues方法。