1. 程式人生 > >Unity資源打包之Assetbundle

Unity資源打包之Assetbundle

nas rar 啟用 大致 ebp 掛載 href 交叉 bundle

本文原創版權歸 csdn janeky 全部。轉載請具體註明原創作者及出處,以示尊重。

作者:janeky

原文:http://blog.csdn.net/janeky/article/details/17652021

假設這篇文章對你有幫助,敬請關註作者《Unity手遊之路》系列教程。

在手遊的運營過程中,更新資源是比不可少的。

資源管理第一步是資源打包。傳統的打包能夠將全部物件制成預設Prefab。打包成場景。今天我們來一起學習官方推薦的Assetbundle。它是Unity(Pro)提供的資源打包策略。利用AssetBundle,能夠將差點兒全部的資源都打包封裝,便於client更新下載新的資源。

(轉載請註明原文出處http://blog.csdn.net/janeky/article/details/17652021)

  • 創建AssetBundle
1.創建一個空的Prefab,命名Cube,然後創建一個Cube,將其拉到剛創建好的Prefab
2.新建一個腳本ExportAssetBundles.cs(代碼來自官方文檔),保存在Asset/Editor文件夾下
這時我們將看到Asset以下出現Build AssetBundle From Selection和Build Scene
3.選中預設Cube,執行Build AssetBundle From Selection。這時會彈出一個保存框,將其命名為cube.unity3d(這裏為了測試方便,放在c盤。實際項目中。我們是須要將他們放在webserver。供全部client下載更新)
4.新建一個場景scene1.unity,上面放置幾個模型,然後保存

5.選中該場景,在之前的ExportAssetBundles.cs腳本中加入打包場景的函數。執行Assets->Build Scene。保存為scene1.unity3d(這裏為了測試方便。也放在c盤)

註意事項
a.AssetBundle的保存後綴名能夠是assetbundle或者unity3d
b.BuildAssetBundle要依據不同的平臺單獨打包,BuildTarget參數指定平臺,假設不指定,默認的webplayer
  • 載入AssetBundle

我們通過一個簡單的代碼來演示怎樣載入assetbundle,包含載入普通asset和場景。

註意事項
a.LoadFromCacheOrDownload 能夠指定版本號。假設本地版本號是新的。將不會從server讀取
b.假設是多個資源打包在一起,我們要通過bundle.Load(),載入特定的資源
c.掛載在模型上的腳本也能夠一起打包。可是保證腳本在原文件夾也要存在,否則載入出來無法執行。關於怎樣更新腳本,我將放在以後的章節中闡述。


  • AssetBundle依賴關系
假設一個公共對象被多個對象依賴。我們打包的時候。能夠有兩種選取。一種是比較省事的,就是將這個公共對象打包到每一個對象中。這樣會有非常多弊端:內存被浪費了。增加公共對象改變了。每一個依賴對象都得又一次打包。

AssetBundle提供了依賴關系打包。

我們通過一個簡單的樣例來學習

我們在程序載入的時候必須保證先載入公共對象。否則,僅僅能是在各個對象載入成功後,再通過程序手動加入進來。比較繁瑣。在實際項目中,因為是團隊開發。對象間的依賴關系一般會比較淩亂。最好在開發周期就定好相關的規範約束。方便管理。
  • 總結

這一節的內容偏實際操作,官方文檔和雨松的blog中已經有更加具體介紹。假設大家還有不明確的地方。能夠結合文檔再實際操作一下。

後面的章節,我將花很多其它的時間介紹核心的內容:資源的增量更新。和代碼程序的更新

  • 源代碼

http://pan.baidu.com/s/1i3BOAPn

  • 參考資料

1.http://www.xuanyusong.com/
2.http://game.ceeger.com/Manual/DownloadingAssetBundles.html

來源:http://www.im286.com/thread-11924518-1-1.html

Assetbundle 是Unity Pro提供提供的功能。它能夠把多個遊戲對象或者資源二進制文件封裝到Assetbundle中,提供了封裝與解包的方法使用起來非常便利。

1.預設

Assetbundle能夠將Prefab封裝起來。這是多麽方便啊。 並且我也強烈建議大家將Prefab封裝成Assetbundle。由於Prefab能夠將遊戲對象身上帶的遊戲遊戲組件、遊戲腳本、材質都封裝在一起。

當從server上將Assetbundle下載以後直接Instantiate就能夠放入遊戲中。

試想一下,假設僅僅能將原始的二進制資源文件放在server上下載,當資源文件完成下載後,須要動態的創建遊戲對象、然後動態的將腳本綁定在遊戲對象、動態的將貼圖賦予遊戲對象等等各種動態的操作。

。所以強烈建議使用Prefa,不解釋!

。!!



另外。我在舉個樣例,由於模型有可能會帶非常多動畫文件,那麽這樣一組模型資源就可能是多個FBX 文件 和 若幹png貼圖文件 材質文件。這時我僅僅須要把原始模型放入Prefab中,它就會包括這個模型的全部組件、甚至包括它的動畫資源、貼圖。

那麽例如以下圖所看到的,Mode就是模型的Prefab文件。那麽我僅僅僅僅須要把Mode這個預設打包成Assetbundle就可以。

當我在server上下載這個Assetbundle而且加載遊戲中就能夠直接使用了,切換動畫、換貼圖都能夠。



2.二進制文件

也並非Assetbundle中全都要用預設。Assetbundle它也能夠將二進制文件直接封裝在裏面。比方圖片、聲音、文本信息等等。



3.場景文件

在Unity中能夠將一個場景保存在Scene中。Scene就會包括這個場景中的全部。那能不能把Scene也封裝成Assetbundle中?答案是能,可是它不能在移動平臺上用,由於移動平臺上是不能更新腳本的,換句話來說就是即使將腳本綁定在Prefab中,然後下載Assetbundle後,全部腳本是不會運行的,後面說第二種巧妙使用方法。

4.移動平臺

上面MOMO已經將Assetbundle 的使用原理大致介紹了一下 ,我們在談談移動平臺。

腳本不能更新是移動平臺下最大的傷,這就意味著開發人員無法繞過App store和 google Play這樣的在線商店升級應用程序。

唯一能做到的就是更新資源、舉個樣例。遊戲中在處理版本號升級時,通常會有個大版本號號和一個小版本號號,大版本號號就是 2.0、3.0這樣的 版本號須要在AppStore中更新。大版本號主要是升級遊戲腳本,然後當小版本號號,比方2.0.1 或2.0.2這樣的僅僅是更新遊戲中的資源。通過自己遊戲的server就能夠完畢。通過Assetbundle在自己server上下載,然後適應在遊戲中。

假設非要更新腳本,或不得不更新腳本那麽僅僅能在Appstore或者google Play去更新大版本號。



移動平臺上不能更新腳本。那麽Prefab上綁定的腳本怎麽辦?在不論什麽平臺上都能夠把腳本加入到Prefab上,然後打包成Assetbundle。僅僅有移動平臺上有點特殊,比方將Test.cs這條腳本綁定在Prefab中。最後程序通過server下載這個Assetbundle ,當加載project中這條腳本是不會被運行的。

可是假設本地project有Test.cs這條腳本。那麽Unity會自己主動將這條腳本綁定在下載的Prefab中。而且他們運行的很好。

假設本地project中沒有Test.cs這條腳本。那麽Prefab上的腳本是永遠都不會運行的。有時我們會在腳本中寫一些Public的變量,有可能不同的Prefab上綁定的是同樣的腳本,僅僅是Inspector 腳本中的public參數不同。別操心這一點Assetbundle 中的Prefab也是沒問題,所以說僅僅要大版本號中的腳本沒問題,在小版本號中僅僅更新遊戲資源是一點問題都麽有的。

5.移動優化

之前我們說過能夠將遊戲中的某個遊戲對象封裝成Assetbundle,也能夠將遊戲中的整個場景也封裝成Assetbundle。可是我覺得須要巧妙的使用封裝場景。由於場景中肯定有非常多公用的模型,假設打包場景的話那麽內存與size就是 公用模型的size * N個場景,想想事實上挺恐怖的。

事實上我們能夠巧妙的使用。首先把場景中公用的部分和私有的部分統統放入Unity, 然後烘培整個場景。 當場景烘培完成後把公用的模型部分在拿出去,場景僅僅僅僅保留私有的模型。還能夠做一個工具將公用模型在場景中的坐標保存在XML中(每一個場景文件會相應一個公用模型的XML信息),最後在將公用的模型分別封裝在別的Assetbundle中。



server上提供每一個場景的Assetbundle ,和公用模型的Assetbundle,一般公用模型的Assetbundle能夠放在常駐內存中(可能使用頻繁、依據項目的不同而定)場景Assetbundle下載完畢後。現加載場景然後在依據場景相應的XML信息將公用模型部分動態的在加入到場景中,這樣就完畢了一個場景的構建。

6.總結

對遊戲中全部資源進行打包。比方按類型分為五個大部分 界面,模型,特效,聲音。場景。腳本。



界面部分:

公用資源包(可復用的資源包)和 每一個界面獨有得資源包(不可復用的資源包)統一使用Prefab 打包成.assetbundle 二進制格式。



模型部分:

按角色分類。統一使用Prefab 打包成.assetbundle 二進制格式。 模型部分包含模型文件與動畫文件。每個模型文件相應一組動畫文件。(假設模型須要換裝還需提供相應換裝的模型與貼圖) ,由於unity4的重定向動畫不支持動態載入。所以眼下不須要考慮 不同大小 不同規格 不同性別 的模型重定向動畫。



特效部分: 統一使用Prefab 打包成.assetbundle 二進制格式。

聲音部分: 統一使用Prefab 打包成.assetbundle 二進制格式。

場景部分:場景和前面的有點差別。場景須要導出烘培的光信息而且僅僅能烘培場景之上永遠不動的模型,可是這些永遠不動的模型有可能會同一時候在多個場景中使用,所以場景烘培完成後要把反復使用的對象刪除,(執行遊戲在動態的載入進來)場景中僅僅保留該場景中永遠不會變的模型,以及烘培的光照信息。 打包場景後會生成.unity3D 二進制格式。它和 assetbundle 打包方式是不同的。

(另外,也能夠考慮 json xml 二進制 來動態組裝場景)。



腳本部分:假設Prefab上是帶腳本打包Assetbundle的話 腳本是不會被執行的(移動平臺), 可是unity有一個技巧。Prefab上的腳本 假設本地有的話它會把本地的同名腳本綁定在Prefab對象上,它會非常好的執行。

Prefab打包技巧: Prefab打包時自身是不占多少空間的 <=1KB 可是Prefab上是能夠關聯 這五大部分 “界面,模型,特效,聲音,場景,腳本”以及在Hierarchy視圖中 坐標/縮放/旋轉。 關聯這些信息以後就會非常大。所以為了避免資源的浪費盡量避免Prefab反復關聯。

一個prefab以下能夠同一時候關聯多個遊戲對象 ,這裏舉個樣例假設你的 Prefab以下放了一個模型 它的大小可能是500k ,在 Prefab以下放了十個全然同樣模型 它的大小可能是501k 。

假設Prefab以下放了兩個不同的模型,它的大小可能就會是 500k x 2 的size ,也就是說Prefab與關聯的數量是無關的 。

加密部分: assetbundle 是能夠轉換成 字節數組 ,client與server約定一組解密 字節數組的算法就能夠實現資源加密。



大版本號升級:

unity的版本號升級事實上主要是升級主程序中的腳本。 由於全部的資源都是assetbundle 和 .unity3d 這些資源放在本地或者server 解包的方式是全然一樣,所以理論上我們的主程序包的大小能夠做到非常小,能夠非常好設置把多少資源放在包裏 或者把所少資源放在server上。在執行的時候服務端應該把全部 assetbundle 和 .unity3d的資源文件的下載地址列表返回給client。

小版本號升級:

小版本號升級也就是更新資源,由於不能更新腳本, 在登陸的時候服務端應該把全部 assetbundle 和 .unity3d的資源文件的下載地址列表返回給client。

還有個須要考慮的地方。比方如今大版本號是2.0.0 。小版本號已經是2.0.5 ,用戶的手機上是一個1.5.0的包。 此時用戶在打開遊戲的時候 應當強制它去appstore中去下載大版本號2.0.0 ,當用戶完成下載後登陸遊戲,此時server告訴client如今已經是2.0.5的小版本號了,這時候client去下載相應小版本號的全部 assetbundle 和 .unity3d文件地址列表。



增量更新:理論上增量更新是可行的。由於unity不能更新腳本。所以在處理增量更新的話 須要在代碼中做能夠兼容增量更新的可能。



由於Assetbundle這塊的代碼比較多。我還是決定分成兩篇文章來寫。這篇文章先說原理、下篇文章說代碼。歡迎大家來討論!

前幾天我和Unity鑫哥聊天,他告訴我IOS上是無法執行時更新腳本、可是Android上是能夠執行時更新腳本。我回家也試了一下可是沒能成功。後來我考慮即使成功了項目中我也不打算那麽做,由於這樣Android和IOS 做起來的區別就太多了, 另外Unity商店中有一個處理執行時更新腳本的插件 unityLua 大家能夠去研究研究。

Unity資源打包之Assetbundle