Unity手遊實戰:從0開始SLG——資源管理系統-Addressable中文手冊(二)開發週期
前面一章節簡介了Addressable Assets System。我們大致可以瞭解到它的優勢就是可以把資源的規劃、構建和載入進行分離,而以往這些都是揉在一起的。
1 傳統的資產管理
如果你把資源規劃在Resources 目錄下,那就表示它們會被構建在你應用的初始包裡,並且你只能使用 Resources。Load的API,並且傳遞一個路徑引數去載入你要的內容。要想在任意地方引用資源的話,你需要將對資源進行直接引用,或者打成 assetBundles。如果使用了assetBundles的話,你還是需要傳遞資源路徑,以及在載入的時候將它們根據一些策略組合起來。如果你的assetBundles在遠端或者有些依賴項在其他的assetBundles裡面的話,你還需要自己寫程式碼去管理下載,載入和解除安裝它們。
2 Addressable 資產管理
給asset 繫結一個地址,然後你就可以透過這個地址去載入它,而不用關注它的位置、目錄或者你怎麼構建這個資源。你可以任意的更換一個可定址資源的名稱、並且不會出問題。你也可以將一個可定址資源移動至Resources 目錄,或者從一個本地的構建策略轉為遠端,或者其他的構建策略而不用修改你的構建或者載入程式碼。
2。1 Asset group schemas
Schemas 定義了一組資料。你可以在Inspector上把一個schemas 繫結到一個asset groups上。這組繫結的Schemas 會決定怎麼構建它下面的資源內容。例如,在 packed mode模式下構建時,帶有BundledAssetGroupSchema模式的組充當 assetBundles的源。還可以將一組Schemas組合成用於定義新group的模板。透過AddressableAssetsSettings 的Inspector面板可以新增Schemas模板。
3 構建指令碼
構建指令碼呈現為專案中實現IDataBuilder介面的ScriptableObject assets 。使用者可以建立自己的構建指令碼,並透過Inspector將它們新增到AddressableAssetSettings物件中。要在Addressables Groups視窗(Window>AssetManagement>Addressables>group)中應用構建指令碼,請選擇Play Mode Script,然後選擇下拉選項。目前,實現了三個指令碼以支援完整的應用程式構建,以及三個用於在編輯器中迭代的播放模式指令碼。
3。1 Play mode scripts
可定址資產包有三個構建指令碼,用於建立Play mode資料,以幫助使用者加速應用程式開發。
Use Asset Database (faster)Use Asset Database (BuildScriptFastMode)允許你在遊戲流程中快速運行遊戲。它直接透過Asset Database載入Asset ,這會在不需要分析器或assetBundle建立的情況下進行快速迭代。
Simulate Groups (advanced)Simulate Groups mode(BuildScriptVirtualMode)在不建立assetBundles的情況下分析佈局和依賴項的內容。asset 透過ResourceManager從assetDataBase載入,就假裝它們是透過包載入的一樣。若要檢視遊戲期間bundles載入或解除安裝的時間,請在Addressables事件檢視器視窗(Window>Asset Management>Addressable>Event Viewer)中檢視asset使用情況。Simulate Groups mode可以幫助您模擬載入策略,並調整內容groups以找到生產和發行版的適當平衡。
Use Existing Build (requires built groups)Use Existing Build最接近於已部署的應用程式生成,但它要求你將資料作為單獨的步驟進行構建。如果不修改Asset,則此模式是最快的,因為它在進入Play模式時不處理任何資料。必須透過選擇Build>New Build>Default Build Script,或者在遊戲指令碼中使用AddressableAssetSettings。BuildPlayerContent()方法,在Addressables組視窗(Window>Asset Management>Addressable>group>group)中構建此模式的內容。
Choosing the right script要應用Play mode script,請從Addressables Groups視窗選單(Window>AssetManagement>Addressable>group)中選擇Play Mode Script並從下拉選項中選擇。在開發和部署過程中,每種模式都有不同的時間階段和資源佈置。下表說明了特定模式有用的開發週期的各個階段。
4 分析和除錯
預設情況下, Addressable Assets只記錄warnings and errors日誌。但可以透過開啟Player settings視窗(Edit > Project Settings。。。 > Player)來啟用詳細的日誌記錄。>Player),導航到Other Settings > Configuration部分,並在 Scripting Define Symbols欄位中新增“ADDRESSABLES_LOG_ALL”。
還可以透過取消選中AddressableAssetSettings物件Inspector中的LogRuntimeException選項來禁用異常。如果有需要,可以使用自己的異常處理程式來實現ResourceManager。ExceptionHandler屬性,但這需要在Addressables完成 runtime initialization之後(參見下面)。
4。1 初始化物件
可以將物件繫結到 Addressable Assets settings,並在執行時將它們傳遞給初始化程式進行處理。CacheInitializationSettings物件在執行時控制Unity的快取API。若要建立自己的初始化物件,請建立一個實現IObjectInitializationDataProvider介面的ScriptableObject。這是負責建立與執行時資料序列化的ObjectInitializationData的系統的Editor元件。
5 內容更新工作流
Unity 建議將遊戲內容分為兩類:
Static 內容,不會更新的靜態內容。
Dynamic 內容,希望更新的動態內容。
在這種結構中,靜態內容附帶在應用程式(或安裝後很快下載),並且駐留在很少的並且較大的bundles中。動態內容駐留在網上,最好是在較小的包中,以儘量減少每次更新所需的資料量。Addressable Assets System的目標之一是使該結構易於使用和修改,並且無需更改指令碼。
但是,Addressable Assets System也可以適應需要更改“靜態”內容的情況,比如你不想釋出一個全新的APP構建。
請注意,在不允許遠端更新的情況下(如許多當前的影片遊戲控制檯,或沒有伺服器的遊戲),每次都應該進行完整的、全新的構建。
5。1 它是如何工作的
Addressables使用內容目錄將地址對映到每個assets,並指定載入地址的位置和方式。為了給你的應用程式提供修改對映的能力,你的原始應用程式必須知道這個目錄的線上副本。若要設定該設定,請在AddressableAssetSettings檢查器上啟用“Build Remote Catalog”設定。這將確保將目錄副本構建到指定路徑並從指定路徑載入。一旦應用程式釋出,這個載入路徑就不能再改變了。內容更新過程會建立目錄的新版本(具有相同的檔名),以便在先前指定的載入路徑上覆蓋對應的檔案。
構建應用程式時,會生成一個唯一的應用程式內容版本字串,該字串標識每個應用程式應該載入哪些內容目錄。給定的伺服器可以包含多個版本的目錄,它們之間不會衝突。我們會將需要的資料儲存在addressables_content_state。bin檔案中。這包括版本字串,以及包含在標記為StaticContent的組中的任何asset的雜湊資訊。預設情況下,此檔案與AddressableAssetSettings。Asset檔案位於同一個資料夾中。
addressables_content_state。bin檔案包含Addressables系統中每個StaticContent asset group的雜湊和依賴資訊。構建到StreamingAsset資料夾的所有groups 都應標記為StaticContent,某些大型遠端group也可以這樣指定。在進行下一步(準備內容更新,如下所述)期間,此雜湊資訊會確定所有的StaticContent組是否包含需要更改的assets,以及是否需要將這些assets轉移到其他地方。
5。2 準備內容更新
如果已經修改了任何StaticContent組中的assets,則需要執行“Check for Content Update Restrictions”命令。這將從靜態組中得到任何修改後的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目錄中。
此資料用於確定自上次構建應用程式以來有哪些assets或依賴項已被修改。為了準備更新內容的生成,系統將將這些assets移動到一個新的group 中。
注意:如果您的所有更改僅限於non-static groups,則此命令將不起任何作用。
重要:在開始prepare operation之前,Unity建議你使用版本控制系統打個分支,並在分支上進行操作。prepare operation會以適合的 updating content 的方式對 asset groups進行重新排列。分支會確保下次再發佈一個新player時,可以快速回滾到你自定義的設定。
5。3 構建內容更新
構建一個內容更新:
1、Unity開啟Addressables Groups視窗。(Window > Asset Management > Addressables > Groups)
2、Addressables Groups視窗,選擇上部的選單 Build,然後選擇Update a Previous Build。
3、在Build Data File 對話方塊開啟的時候,選擇一個已經存在的APP構建的構建目錄,這個目錄下必須要包含contain an addressables_content_state。bin 檔案。
構建會生成一個內容目錄、一個Hash檔案和asset bundles。
生成的內容目錄具有與選定應用程式生成中的目錄相同的名稱,並且會覆蓋舊目錄和hash檔案。應用程式會載入hash檔案來確定新目錄是否可用。系統從應用程式附帶的或已經下載的現有asset bundles中載入未經修改的assets 。
系統使用addressables_content_state。bin檔案中的內容、版本、字串和位置資訊來建立asset bundles。不包含更新內容的asset bundles的檔名和原來的一樣。如果asset bundles包含更新的內容,則生成包含更新內容的新asset bundles,該包會具有新的檔名,以便與原始檔案共存。帶有新檔名的asset bundles必須複製到指定的內容託管位置。
系統還可以為靜態內容構建asset bundles,但是並不需要將它們上傳到內容託管位置,因為沒有Addressableasset entries 引用它們。
5。4內容更新樣例
在本例中,需要了解以下組概念:
當此版本處於活動狀態時,有些玩家的裝置上有Local_Static,並且可能還在本地快取了其中一個或兩個遠端包。
如果你從每個group (AssetA、AssetL和AssetX)修改了一個asset ,那麼執行Check for Content Update Restrictions,本地Addressable設定中的結果現在是:
請注意,prepare operation實際上就是編輯靜態組,這可能會與正常的理解有衝突。系統會自動構建上述佈局,但是任何靜態groups都會丟棄生成結果。因此,您將從玩家的角度得出以下結論:
LocalStatic bundle已經在玩家的裝置上,所以不能更改它。這個舊版本的AssetA不再被引用。相反,它被殘留在玩家裝置上,作為垃圾資料。
Remote_Staticbundle保持不變。如果它還沒有快取在玩家的裝置上的話,當請求AssetM或AssetN時,它將會被下載。像AssetA一樣,這個舊版本的AssetL不再被引用。
Remote_non-Static包現在已經過時了。您可以從伺服器中刪除它,但無論是哪種方式,都不會再從這裡下載了。如果已經快取了,那麼它會一直留在快取。像AssetA和AssetL一樣,這個舊版本的AssetX也不再被引用。
舊的Remote_non-Staticbundle 被替換為一個新版本,該版本由hash檔案來區分。修改後的AssetX版本將使用這個新bundle進行更新。
content_update_group的 bundle將由被引用的、修改後的assets組成。
注意,上面的示例具有以下意義:
1、任何更改後的本地assets 都會永久殘存在在使用者的裝置上。並且保持未使用狀態。
2、如果使用者已經快取了一個非靜態bundle,他們將需要重新下載包,包括未更改的assets(例如,AssetY和Assetz)。理想情況下,使用者沒有快取bundle,在這種情況下,他們只需要下載新的Remote_non-Static包。
3、如果使用者已經快取了Static_Remote bundle,他們只需要下載更新的asset (在本例中,透過content_update_group下載AssetL)。但這種情況是很理想的。如果使用者沒有快取過bundle,則必須透過content_update_group下載新的AssetL,並透過未引用的Remote_Static bundle下載現已失效的AssetL。不管初始的快取狀態如何,在完成的某個時候,使用者都會在他們的裝置上擁有已停用的AssetL,儘管從未被訪問或者引用過,但卻會被永久的快取。
遠端內容的最佳設定將取決於你怎麼去使用。