關注公—眾—號“游戲內圈”,更多免費資料和教程等着你
1.什么是資源?
在Unity的Assets目錄下的文件,在游戲運行過程中需要從此目錄加載並顯示到屏幕上的都可以稱之為Unity資源,例如模型、材質、紋理、預制體、腳本、聲音、數據文檔、動畫切片、控制器、着色器、場景等。
2.如何管理資源?
在Unity中如果希望能非常良好地管理這些游戲資源,就必須考慮以下幾點因素:
統一資源格式
制作一個Unity的資源格式標准,所有資源都采用這個相同的格式進行處理。傳統格式如XML、JSON可以實現此功能,但是其安全性低、無任何加密並且打包加載速度非常慢因此並不是理想選擇。
統一資源處理流程
制作(打包)資源:將游戲中的任何一類資源打包成統一的資源包格式。
使用(加載)資源:解析這個資源包並將其所包含的具體資源加載到內存中使用。
釋放(卸載)資源:將不再使用的資源釋放掉以節約內存空間。
Unity官方決定采用一套自主研發的完整資源解決方案稱為AssetBundle,又簡稱AB包。
什么是AssetBundle?
AssetBundle是將資源用Unity的一種用於存儲資源的壓縮格式打包后的集合。它可以存儲任意一種Unity引擎可以識別的資源。
Unity中的AssetBundle系統是對資源管理的一種擴展,可以動態地加載和卸載,並且大大節約了游戲包體所占空間並提高了加載效率。

創建AssetBundle
目前Unity提供了4.x與5.x兩種AssetBundle資源包的創建方式。其中4.x是老版方式,相對比較麻煩,只能在打包腳本中通過純代碼的方式手工指定AB包與資源列表依賴關系。而5.x的方式做了很大改進,提供了AssetBundle創建工具,開發者可以通過該工具非常簡單方便的進行編輯器操作指定AB包與資源依賴關系,可以大大提高開發效率。
然而無論使用哪種方式,開發者都需要在Unity編輯器中編寫腳本來創建AB包,由於打包操作是在游戲非運行時,因此這個腳本一定能夠在不運行游戲的前提下執行,Unity提供了編輯器擴展的功能來幫助開發者實現這個目的。
1.什么是編輯器擴展?
Unity編輯器擴展其實主要是指開發者通過編寫C#腳本從而在Unity編輯器中添加一個新的工具菜單項來對現在的編輯器功能進行擴展或更為簡單的實現管理資源的功能。這個C#腳本稱之為編輯器擴展腳本。在使用編輯器擴展時需要注意以下3點:
必須在編輯器腳本中使用@MenuItem特性聲明編輯器菜單項函數以用來實現相應的菜單功能。
編輯器腳本必須放在名為Editor的文件夾下。
在編輯器的菜單回調函數中實現菜單點擊功能(不能是游戲運行時的功能)。

2.Unity5.x打包
(1)給每一個資源通過AB打包工具指定AB包名稱(編輯器中)
(2)在打包腳本中調用public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform)將標記的資源全部打入對應的AB包。
outputPath:AB包的輸出路徑,必須預先創建否則會打包時報錯。
assetBundleOptions:為AB包構建選項,默認情況下只要選擇None就可以了。
targetPlatform:為AB包的目標平台,游戲發布不同的平台此選項不同。
特別注意:
一個AB包對應兩個文件,其中一個只包含資源內容本身,無后綴是一個二進制壓縮文件,另外一個后綴為.manifest是對這個AB包的描述文件,其中描述了AB包中的資源列表以及依賴關系。
而在打包目錄會額外生成一個與輸出路徑名稱一樣的全局AB包,它的描述文件中表示了此目錄下的AB包列表以及依賴關系。

加載AssetBundle
1.加載AB包大致可以分為兩個步驟:
讀取AB包資源數據到程序內存。
使用AssetBundle.LoadFromFile(path),其中path是AB的路徑,返回AssetBundle對象。
加載AB包中存儲的具體資源對象並使用。
2.加載AB包中具體資源對象
(1)AssetBundle.LoadAsset方法,參數傳遞具體資源名稱,不帶后綴。使用泛型的方法可以自動加載並返回相應資源類型,使用不帶泛型方法會返回Object,需要手動轉換。
(2)AssetBundle.LoadAllAssets方法,無參一口氣加載所有包中的資源到內存。使用泛型的方法那么返回的是一個特性類型的數組(前提是包中的資源都是相同數據類型),使用不帶泛型的方法會返回Object數組(可以是不同類型對象)。

卸載AssetBundle
正確的做法是對於程序中確定不再使用的AssetBundle資源包,我們要及時卸載調優化內存空間來保證可以順利加載新的資源。
Unity中只有一個負責卸載AssetBundle的方法,需要傳入一個布爾類型參數,取true和false兩個值含義完全不同,具體如下:
1.AssetBundle.Unload(false)
釋放AssetBundle文件的內存鏡像,不包含已經被加載到內存中的資源對象。
2.AssetBundle.Unload(true)
釋放AssetBundle文件的內存鏡像,並銷毀所有資源對象,無論是否加載。


特殊資源處理
絕大多數AssetBundle資源使用上述流程和方法都可以正確處理,但是實際開發中仍然存在兩類資源需要進行特殊處理。
1.腳本資源
腳本資源是一種特殊資源,腳本本身代碼內容不會被打入AB包,而是只會在AB包中維護一個腳本的引用,其直接指向Assets目錄下的某一個具體名稱腳本,加載AB包的時候就要求在Assets目錄下必須存在所有此包中資源依賴的同名腳本,否則造成所有資源的腳本丟失(物體行為邏輯丟失)。
2.場景資源
同腳本一樣,場景資源也是一類極為特殊的游戲資源。在Unity中場景資源不能和其他普通資源混合打入同一個AssetBundle,必須單獨打入AB包。而是當我們加載並使用AB包中的場景時(一般情況下是切換場景操作),不再需要預先將場景添加到Scens In Build場景構建列表,直接使用就可以了。

Unity4.x打包流程
不同於Unity5.x,Unity4.x沒有方便的AssetBundle打包工具,只能通過在腳本中純代碼方式指定資源列表和依賴關系。
資源依賴打包與依賴加載
總結就是:如果是需要多個資源依賴的資源,建議放入公共包
1.資源的依賴打包
AssetBundle中不同的bundle的許多資源可能會同一時間依賴於相同的某個資源,例如不同模型可能會引用相同的材質,這稱為AssetBundle資源之間的依賴。如果不考慮依賴關系,將兩個資源分別打包到兩個不同AB包中,那么它們共享的材質資源就會被打包兩次,這就造成了資源的浪費。
為了避免這種浪費,需要使用AssetBundle的包依賴關系來處理。正確做法是將共享的材質資源單獨打包到一個獨立的AssetBundle中,讓兩個模型所隸屬的AB包分別依賴於該獨立材質AB包,這樣材質資源僅會被打包一次,節省了游戲資源空間。從Unity5.x開始,系統會自動判斷所有AB包的資源之間的依賴關系,不需要開發者手動處理。
2.資源的依賴加載
如果要加載一個帶依賴關系的AB包,那么必須首先加載它所依賴的所有其他AB包,否則此AB包中使用Load加載的對象將會丟失依賴的資源關聯。
還存在另外一種情況,當嘗試加載N個帶有依賴關系的AB包時,其實很難預先知道每一個AB包所依賴的其他資源列表,因此這部分依賴關系信息就需要在程序運行時動態獲取。AssetBundle提供了一個名為GetAllDependencies的方法專門用於獲取當前AB包所以來的資源列表,這樣就可以在程序中預先加載所有依賴的AB包了。
————————————————
版權聲明:本文為CSDN博主「heliocentricism」的原創文章,遵循CC 4.0 BY-SA版權協議,
原文鏈接:https://blog.csdn.net/heliocentricism/article/details/109209801