AssetBundle詳解與優(yōu)化

1. AssetBundle原理

AssetBundle是Unity中的一種資源包郊尝,這種資源包可以是游戲內(nèi)要用到的幾乎所有資源,例如:模型粗悯、紋理虚循、預(yù)設(shè)、場景等大部分文件更新样傍,并且可以在運(yùn)行時(shí)動(dòng)態(tài)加載横缔。

值得注意的是AssetBundle是可以多個(gè)文件一起打包,例如將要打包的資源做成預(yù)設(shè)后再進(jìn)行打包衫哥,這樣可以將預(yù)設(shè)上面附帶的組件茎刚、紋理、子對象等一并打包撤逢,加載后直接實(shí)例化就能直接使用了(并不是建議大家這么做膛锭,因?yàn)樯婕暗募y理材質(zhì)可能會(huì)造成資源冗余)。

另外AssetBundle 可以選擇壓縮后再進(jìn)行網(wǎng)絡(luò)傳輸蚊荣,提升傳輸效率初狰,減少包體大小等,不同的壓縮方式互例,我們放后面對比一下優(yōu)劣奢入。

那么使用AssetBundle可以解決的問題是:

1.1 實(shí)現(xiàn)資源的熱更。

1.2 減少初始包體大小媳叨,游戲可以做分包處理腥光。

1.3 ?可以利用二進(jìn)制文件做資源加密。

2. AssetBundle壓縮

以下我僅作 lzma和lz4的壓縮測試結(jié)果進(jìn)行總結(jié)糊秆,未壓縮和自定義在此暫不作比較武福。

2.1 文件大小和下載速度。lzma的壓縮大小比lz4小痘番,所以下載的速度lzma也比lz4的速度要快捉片。

2.2?加載開銷。運(yùn)行時(shí)加載開銷lz4要優(yōu)于lzma不少。

2.3?加載時(shí)內(nèi)存占用界睁。在使用LoadFromFile(Async)加載lzma格式的AB包時(shí)觉增,內(nèi)存的占用會(huì)是資源文件內(nèi)存的大約2倍兵拢,而使用lz4則是跟資源文件內(nèi)存大小一致的翻斟。

總結(jié)是lz4無論是解壓時(shí)間、加載開銷和內(nèi)存占用都優(yōu)于lzma说铃,但唯一的缺點(diǎn)就是包體會(huì)大不少(約25%)左右访惜。所以如果想要包體小,且加載速度又快腻扇,我們可以使用GZip把資源在打包完之后再打個(gè)壓縮包债热,這樣的話包體也會(huì)小很多。

3. AssetBundle加載

我們從幾種AssetBundle本地加載進(jìn)行比較?new www幼苛,AssetBundle.LoadFromFile對其優(yōu)劣進(jìn)行分析比較窒篱。

3.1 new www 其優(yōu)點(diǎn)是即可網(wǎng)絡(luò)加載又可加載本地,而其缺點(diǎn)是這種方式加載資源舶沿,所占的內(nèi)存要比LoadFromFiles高墙杯,相比LoadFromFile加載速度也會(huì)要慢一些。

3.2?AssetBundle.LoadFromFiles是目前版本最推薦的加載本地AssetBundle的方式括荡,從性能上目前是最好的高镐,內(nèi)存占用相比new www也要小。(本地加載www沒有可比性)

綜上所述畸冲,推薦大家使用www來下載由多個(gè)AB包壓縮生成的壓縮包嫉髓,下載然后解壓到本地后再通過LoadFromFile來加載,這樣的做法又快又高效邑闲,資源還小算行。

4. AssetBundle卸載

AssetBundle在使用過程中很容易產(chǎn)生卸載不干凈,繼而導(dǎo)致資源的冗余苫耸,強(qiáng)行卸載又可能導(dǎo)致資源丟失引用州邢。如何卸載AssetBundle是值得深入研究的一件事。

4.1?AssetBundle.Unload(false)鲸阔。?參數(shù)為false時(shí)偷霉,AssetBundle內(nèi)的序列化數(shù)據(jù)會(huì)被釋放,實(shí)例化的物體還都保持完好褐筛。簡單的說就是斷開了AssetBundle和實(shí)例之間的聯(lián)系类少。值得注意的是這樣做并不會(huì)卸載AssetBundle,意思是AssetBundle還會(huì)繼續(xù)占用內(nèi)存渔扎。然而如果再次實(shí)例化對象硫狞,也不會(huì)返回以前初例化過的AssetBundle,而是重新實(shí)例化一個(gè)新的AssetBundle,那么這樣就出現(xiàn)了冗余残吩,同樣的資源财忽,內(nèi)存中會(huì)出現(xiàn)多份。所以適合這樣來卸載的資源泣侮,一定是不需要多次創(chuàng)建實(shí)例的資源即彪,例如:一次性使用的配置信息。而卸載的話要當(dāng)創(chuàng)建的實(shí)例刪除回收以后活尊,手動(dòng)調(diào)用Resources.UnloadUnusedAssets或切換場景來釋放隶校。

4.2?AssetBundle.Unload(true)。參數(shù)為true時(shí)蛹锰,就簡單多了深胳,卸載AssetBundle,并且刪除被引用的資源铜犬。注意舞终!如果AssetBundle中有資源在場景中被引用,則會(huì)出現(xiàn)資源丟失的情況癣猾。這種卸載方式敛劝,最為徹底,完全從內(nèi)存移除煎谍,缺點(diǎn)是你需要一套機(jī)制攘蔽,來關(guān)注是不是還有資源引用,會(huì)不會(huì)引起異常呐粘。

4.3 關(guān)于卸載資源中满俗,必須要跟大家說明的是,加載的AssetBundle作岖,可以通過Resources.UnloadUnusedAssets來釋放唆垃。但是前提是加載的AssetBundle一定要先釋放干凈,即沒有任何引用痘儡。在調(diào)用AssetBundle.Unload(true)后會(huì)強(qiáng)行刪除創(chuàng)建的實(shí)例和引用辕万;而AssetBundle.Unload(false),必須先手動(dòng)刪除資源的實(shí)例和引用才能釋放沉删。另外Resources.UnloadUnusedAssets的開銷其實(shí)并不薪ツ颉(因?yàn)椴粌H僅是釋放AssetBundle還包括Resources.Load的其他資源),建議每隔一段時(shí)間進(jìn)行調(diào)用比較合適矾瑰。

那么給大家總結(jié)下使用卸載方案吧砖茸。

AssetBundle.Unload(false)適用于一次性使用的資源,獲得資源引用后直接調(diào)用殴穴,當(dāng)刪除引用后凉夯,下次調(diào)用Resources.UnloadUnusedAssets后就刪除了货葬。AssetBundle.Unload(true)在使用中,最好的做法是給創(chuàng)建出來的實(shí)例都添加計(jì)數(shù)劲够,當(dāng)計(jì)數(shù)不為0時(shí)震桶,表示場景或代碼中仍有引用,而當(dāng)計(jì)數(shù)為0時(shí)征绎,表示沒有引用了蹲姐,這樣就可以放心大膽的AssetBundle.Unload(true)了。

5. AssetBundle依賴打包注意事項(xiàng)

依賴打包最需要注意的也是唯一要注意的就是要避免依賴的處理不當(dāng)炒瘸,而導(dǎo)致資源冗余淤堵。

5.1 對于引用的資源,必須明確出現(xiàn)在其他AssetBundle的資源列表中顷扩,Unity才能識(shí)別為依賴關(guān)系,形成依賴打包慰毅。

5.2?合理規(guī)劃AssetBundle包隘截,公共的資源單獨(dú)抽離打包。

5.3?注意資源與AssetBundle的關(guān)系汹胃,一個(gè)AssetBundle可以包含多個(gè)資源婶芭,但同一份資源不允許存在于多個(gè)AssetBundle中。

6. AssetBundle打包策略和建議

在打包之前首先要按照資源類型和邏輯進(jìn)行分組着饥,接下來我們討論下分組犀农,當(dāng)然這里只是討論如果要分組的情況,我們也可根據(jù)項(xiàng)目實(shí)際情況宰掉。

因?yàn)槊總€(gè)項(xiàng)目在AssetBundle分組情況有多種選擇呵哨,有些項(xiàng)目甚至選擇的是全顆粒化增量更新的模式轨奄。因此該小節(jié)暫不作建議和說明孟害。

7. AssetBundles瀏覽與檢測

要檢測資源是否冗余,推薦使用AssetBundles-Browser挪拟、UnityStudio挨务、disunity、UWA GOT等工具進(jìn)行檢測玉组。

8. AssetBundles 好用的開源庫

嗯赚哗,以下排名不分先后航徙,都是很好用的開源庫,不過一些特殊功能,例如:加密赊堪、AssetBundle差異合并、打包策略等喘帚,還需要根據(jù)具體的項(xiàng)目加以實(shí)現(xiàn)矾踱。

MonsterABSystem

ABSystem

KSFramework

xasset

zcode-AssetBundlePacker

以上開源庫均可在github上搜到户辱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市糙臼,隨后出現(xiàn)的幾起案子庐镐,更是在濱河造成了極大的恐慌,老刑警劉巖变逃,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件必逆,死亡現(xiàn)場離奇詭異,居然都是意外死亡揽乱,警方通過查閱死者的電腦和手機(jī)名眉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凰棉,“玉大人损拢,你說我怎么就攤上這事∪鱿” “怎么了福压?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長或舞。 經(jīng)常有香客問我荆姆,道長,這世上最難降的妖魔是什么映凳? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任胆筒,我火速辦了婚禮,結(jié)果婚禮上诈豌,老公的妹妹穿的比我還像新娘仆救。我一直安慰自己,他們只是感情好队询,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布派桩。 她就那樣靜靜地躺著,像睡著了一般蚌斩。 火紅的嫁衣襯著肌膚如雪铆惑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天送膳,我揣著相機(jī)與錄音员魏,去河邊找鬼。 笑死叠聋,一個(gè)胖子當(dāng)著我的面吹牛撕阎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碌补,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虏束,長吁一口氣:“原來是場噩夢啊……” “哼棉饶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起镇匀,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對情侶失蹤照藻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后汗侵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幸缕,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年晰韵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了发乔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雪猪,死狀恐怖栏尚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浪蹂,我是刑警寧澤抵栈,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站坤次,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏斥赋。R本人自食惡果不足惜缰猴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疤剑。 院中可真熱鬧滑绒,春花似錦、人聲如沸隘膘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弯菊。三九已至纵势,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間管钳,已是汗流浹背钦铁。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留才漆,地道東北人牛曹。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像醇滥,于是被迫代替她去往敵國和親黎比。 傳聞我的和親對象是個(gè)殘疾皇子超营,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354