Unity3D研究院之Assetbundle的實戰(六十三)

http://www.xuanyusong.com/archives/2405html

 

上一篇文章中咱們相惜討論了Assetbundle的原理,若是對原理還不太瞭解的朋友能夠看這一篇文章:Unity3D研究院之Assetbundle的原理(六十一) 本篇文章咱們將說說assetbundle是如何實現的。android

1.建立Assetbundleweb

         不管是模型資源仍是UI資源,最好是先把他們放在Prefab中,而後在作成Assetbundle。咱們以模型來舉例,Assetbundle中能夠放一個模型、也能夠放多個模型,它是很是靈活了那麼最須要考慮的就是模型空間佔用的問題。數組

好比咱們有兩個徹底同樣的模型,可是他們身上綁定的腳本不同,此時須要把這兩個模型放在兩個不一樣Prefab中。以下圖所示,咱們分別對這兩個Prefab打包,咱們能夠清晰的看到兩個相同的Prefab打包在一塊兒只佔1M空間,而將他們分別打包會佔1 + 1 = 2M空間。 Prefab在打包的同時會把模型身上的全部材質、貼圖、組件、腳本所有包含進去。緩存

Unity3D研究院之Assetbundle的實戰(六十三) - 雨鬆MOMO程序研究院 - 1

         由此可得相同的模型儘可能打包在一塊兒,他們會公用一套資源文件。不相同的模型儘可能分開打包,相同模型具備不一樣的腳本、組件的話把他們放在不一樣的Prefab中,最後把這些Prefab一塊兒打包在一個Assetbundle中。以下圖所示,如今Project視圖中選擇須要打包的Prefab,而後在導航菜單欄中選擇Create Assetbundles Main表示分別打包、Create AssetBundles All表示將他們打包在一塊兒。服務器

Unity3D研究院之Assetbundle的實戰(六十三) - 雨鬆MOMO程序研究院 - 2

        這兩個prefab文件都指向了同一個模型,爲了讓它倆有所區別,我給它倆綁定了相同的腳本,可是腳本中的參數是不一樣的。在編輯器上給每一個Prefab賦值一個不一樣的名子,而後在Awake方法中進行輸出。異步

 

Create Assetbundles Main : 分開打包,會生成兩個Assetbundle。編輯器

 

最核心的方法其實就它:學習

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)測試

參數1:它只能放一個對象,由於咱們這裏是分別打包,因此經過循環將每一個對象分別放在了這裏。

參數2:能夠放入一個數組對象。

默認狀況下打的包只能在電腦上用,若是要在手機上用就要添加一個參數。

Android上:

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android)

IOS上:

BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)

另外,電腦上和手機上打出來的Assetbundle不能混用,不一樣平臺只能用本身的。

 

Create AssetBundles All:將全部對象打包在一個Assetbundle中。

 兩次打包完畢後,在StreamingAssets文件夾中就看到了這三個assetbundle文件。

 

Unity3D研究院之Assetbundle的實戰(六十三) - 雨鬆MOMO程序研究院 - 3

2.讀取Assetbundle 

       而後咱們來學習如何運行時讀取Assetbundle,Assetbundle是能夠同時放在服務器或者本地的,不管放在哪裏兩種下載讀取的方式是徹底同樣的。因此我建議在作unity項目的時候開始就把資源放在Assetbundle中在本地來作,等作的差很少了直接把Assetbundle放在服務器上,由於兩種讀取的方式徹底同樣,這樣之後更新資源會方便不少。而後是讀取,而且加載到遊戲中。

 這裏咱們詳細的說說 下載類WWW

WWW bundle = new WWW(path);

這樣的作法是經過一個路徑進行下載(不管是服務器路徑仍是本地路徑下載操做都同樣)可是bundle只能保存在內存中,也就是退出遊戲在進入還得從新下,很顯然在遊戲中咱們不能使用這種方式。

 

 

使用的方法是WWW.LoadFromCacheOrDownload(path,5);

參數1:服務器或者本地下載地址

參數2:版本號

         Unity會下載Assetbundle本地中,它的工做原理是先經過(版本號和下載地址)先在本地去找看有沒有這個Assetbundle,若是有直接返回對象,若是沒有的話,在根據這個下載地址從新從服務器或者本地下載。這裏版本號起到了很重要的做用,舉個例子,同一下載地址版本號爲1的時候已經下載到本地,此時將版本號的參數改爲2 那麼它又會從新下載,若是還保持版本號爲1那麼它會從本地讀取,由於本地已經有版本號爲1的這個Assetbundle了。你不用擔憂你的資源本地下載過多,也不用本身手動刪除他們,這一切的一切Unity會幫咱們自動完成,它會自動刪除掉下載後最不經常使用的Assetbundle ,若是下次須要使用的話只要提供下載地址和版本後它會從新下載。

        咱們在聊聊Assetbundle 中的腳本,在移動平臺下Assetbundle裏面放的腳本是不會被執行的,還記得咱們打包前給兩個Prefab掛上了腳本嗎?在手機上將Assetbundle下載到本地後,加載進遊戲中Prefab會自動在本地找它身上掛着的腳本,他是根據腳本的名來尋找,若是本地有這條腳本的話,Prefab會把這個腳本從新綁定在自身,而且會把打包前的參數傳遞進來。若是本地沒有,身上掛的條腳本永遠都不會被執行。

      在Prefab打包前,我在編輯器上給腳本中的變量 name 賦了不一樣值,當Prefab從新載入遊戲的時候,它身上腳本的參數也會從新輸出。

Unity3D研究院之Assetbundle的實戰(六十三) - 雨鬆MOMO程序研究院 - 4

若是你的Assetbundle中的Prefab上引用的對象,那麼這樣作就會出錯了,你須要設定他們的依賴關係。或者運行時經過腳本動態的載入對象。

 

http://docs.unity3d.com/Documentation/ScriptReference/BuildPipeline.PopAssetDependencies.html

 

http://docs.unity3d.com/Documentation/ScriptReference/BuildPipeline.PushAssetDependencies.html

像這樣從新打包就能夠。

 

3.打包場景

     上面咱們說過了打包Prefab,其實咱們還能夠把整個場景進行打包,由於移動平臺不能更新腳本,因此這個功能就會有所限制,個人建議是烘培場景、而後把多個場景可複用的對象移除,場景中只保留獨一無二的遊戲對象,而後在打包場景,運行遊戲時載入場景後,在動態的將以前移除的對象從新添加進來。

能夠參考 : Unity3D研究院之將場景導出XML或JSON或二進制而且解析還原場景(四十二)

          不一樣平臺下須要選擇  BuildTarget.Android 和 BuildTarget.iPhone 。 切記這段代碼是把Level.unity常見文件打包到MyScene.unity3d文件中,因此在解包的時候也應當是先解開MyScene.unity3d,而後在去加載Level.unity場景,無需在ProjectSetting中註冊新場景。

 

          在測試狀況下你可能會頻繁的打包生成Assetbundle,若是忘記改版本號的話可能會讀取以前的緩存,可能就會看不到新的效果,因此我建議在bunild Assetbundle的時候強制清空一下緩存。

Caching.CleanCache();

最後點擊按鈕進行加載Assetbundle和 Scene吧。

Unity3D研究院之Assetbundle的實戰(六十三) - 雨鬆MOMO程序研究院 - 5

最後是下載地址:http://vdisk.weibo.com/s/Hrvea

歡迎你們一塊兒學習,歡迎給我留言、歡迎一塊兒討論,祝你們學習愉快 啦啦啦啦。

 

2014年10月補充

WWW.LoadFromCacheOrDownload 這個方法建議你們之後不要再用了

由於是異步方法,並且還佔用內存。

強烈建議使用AssetBundle.CreatFromFile 它是一個同步方法。如今IOS 和 android 都支持了,強烈建議用。

打包的時候須要選擇不壓縮。

由於不壓縮, 因此就須要咱們本身來壓縮資源了, 能夠用LZMA 和 GZIP來進行壓縮。

1.打包出來的Assetbundle咱們本身用LZMA壓縮,上傳到服務器上。

2.IOS或者Android下載這些assetbundle

3.解壓縮這些assetbundle而且保存在Application.persistentDataPath 目錄下。

4.之後經過AssetBundle.CreatFromFile  讀取assetbundle。

此法確實可行,咱們已經在實際項目中轟轟烈烈的使用了。。

相關文章
相關標籤/搜索