天天看點

Unity之AssetBundle原理全解

需要修改 不完善 請别細看

AssetBundle:首先我們需要對這個名稱有個概念他到底是什麼東西,我們建構遊戲裡面有音樂,貼圖,材質,預設等各種資源組拼成一個好玩的遊戲。這些都是AssetBundle嗎,No,Unity中很簡單你在對應資源窗體下面給資源上包名才算。上圖;

Unity之AssetBundle原理全解

好了我們就以為可以設定成這個東西,我們就可以寫打包工具Build成AB包,并且會放在一個特殊檔案夾裡,名字固定死了StreamingAssets.這個是我們打包之前的準備工作完畢。

下面步入打包原理正題:

不得不說我看了網上很多對AB的講解感覺有點官方不太好了解,那麼我談AB原理之前先講一個故事:

希望大大好好看,假如我由于技術比較牛逼,突然有一天騰訊企鵝大佬說要挖我過去上班,當然二話不說去呗。這個時候麻煩了我住的地方塞滿了比較貴重的各種物品。怎麼辦我在新的公司需要用啊,又舍不得丢掉他們重新買。是以我就打算走快遞,我就把這些物品打包在一個袋子裡壓得緊緊的,這個袋子我們可以看成是AssetBundle他裡面有各種物品。我用了什麼絕招把本來要占大空間的放入了一個小袋子,這個時候我打電話通知快遞拿包給寄到我新公司。這個是不是可以看成WWW www = new WWW(url)呢。可以當然unity對遊戲裡的資源包進行壓縮。這樣有什麼好處友善快遞員運輸啊,以及網絡傳輸更加快。快遞還真快才一天我的包就到了。我就和快遞員見面拿貨,等價于www.assetbundle.這樣我是不是拿到了我以前打的那個包裹呢,我拿到包裹後肯定要拆包啊,這個動作就是在解壓壓縮包。這個就和我拆包裹不同,我解壓包後其實我那個壓縮包還是存在記憶體,這個時候等于我記憶體裡面存在一個壓縮包和解壓後的包。好了我餓了。我想拿出裡面的鍋炒菜啊。好了既然我的包裹被拆了我是不是可以拿鍋炒菜對不對,對。炒菜就直接炒了就一個鍋。但是我們在遊戲裡,想去解壓包裡拿裡面的比較音樂資源去播放音樂,需要通過AssetBundle.LoadAsset接口去拿到一個音樂資源。這個時候資源是如何變得。其實是我們去解壓的一個總包裹裡找到音樂資源。然後開了一片記憶體把需要的音樂資源放在這個記憶體,包裹裡的解壓檔案沒有任何少。

現在談我們需要的是預設資源的情況。這個我們不能直接拿來用。而是需要Instantiate出來。這個時候是怎麼進行的。和上次加載音樂檔案差不多。我們先要把預設提取到記憶體。然後我們通過克隆的方式執行個體。這樣記憶體又會多了份預設的拷貝。然後這個預設就可以顯示了。完工。

現在談解除安裝不用的資源,比如我們需要切換場景了。上個場景的資源如果沒有解除安裝,會發現記憶體洩漏。

我們從www開始。也就是假如我們開始打算寄包裹的情景。www = null ||www.dispose. 我們通過這個方法可以釋放new www占用的全部資源。www我們可以看成是一個快遞員。我們寄完東西後,就需要和快遞員切斷一切聯系,不然他天天打電話騷擾你。好了注意上面說過我們拆包裹的時候,比如取裡面的鍋。

我們的壓縮包和拆後的包都存在。我們需要清掉他們釋放記憶體。assetBundle.unload(false)注意這個需要和assetBundle.unload(true)區分開。前面釋放的是一個壓縮包和解壓後的包。 後面釋放壓縮包和解壓後的包并且還把在這個解壓包提前存在其他記憶體的資源也給你清理了。這個情況你們可能會遇到後後面的解除安裝資源方法就會出現明明場景的物品本來顯示突然就不見了就是因為你把那個物品依賴的資源解除安裝了導緻的。

還有一個情況就是比如我加載的音樂資源已經播完了以後不用了啊。我們要清理掉就用Resource.UnLoadAsset(“.mp3”)這個是具體指定解除安裝哪個資源。還可以直接Resource.UnLoadUnusedAsset();這個接口會找提取出來的資源并且沒有誰引用他就解除安裝掉。但是你執行個體化出來的也不想顯示了必須解除安裝就必須Destory來處理。不同分工不同結果。

現在讨論AB之間的依賴:首先我們要搞清什麼叫包之間有依賴關系,假如我一個預設他用了一個材質。我在給這個預設打包。我問你這個預設包在執行個體化出來會因為材質的原因報錯嗎,也就是這個時候會依賴這個材質,肯定不是。為什麼因為材質并沒有打成一個包。如果材質也打包了。我們預設也打包了那麼我執行個體化預設之前必須先加載這個材質包也就是預設依賴的包,這個就是依賴打包的順序問題。那麼回到一個疑問。既然預設和材質可以打成一個包。為啥要打2個包多了依賴打包這個麻煩啊。肯定是有好處。是什麼呢,整體而言減少重複打包減少計算機資源。比如2個預設都共享一個材質,如果單獨給2個預設打包。就會在每個 包都有一個材質,這樣我們會加載2個材質到記憶體,浪費記憶體。那麼我們就給2個預設和材質分别打包成3個包。我們在用預設的時候先加載出材質包,在加載預設,在執行個體化就顯示出了。

待續

繼續閱讀