【unity】Assetbundle的原理

http://www.xuanyusong.com/archives/2373算法

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

1.預設數組

         Assetbundle能夠將Prefab封裝起來,這是多麼方便啊! 並且我也強烈建議你們將Prefab封裝成Assetbundle,由於Prefab能夠將遊戲對象身上帶的遊戲遊戲組件、遊戲腳本、材質都封裝在一塊兒。當從服務器上將Assetbundle下載之後直接Instantiate就能夠放入遊戲中。服務器

         試想一下,若是隻能將原始的二進制資源文件放在服務器上下載,當資源文件下載完畢後,須要動態的建立遊戲對象、而後動態的將腳本綁定在遊戲對象、動態的將貼圖賦予遊戲對象等等各類動態的操做。。因此強烈建議使用Prefa,不解釋!!!!!app

 

   另外,我在舉個例子,由於模型有可能會帶不少動畫文件,那麼這樣一組模型資源就多是多個FBX 文件 和 若干png貼圖文件 材質文件。這時我只須要把原始模型放入Prefab中,它就會包含這個模型的全部組件、甚至包括它的動畫資源、貼圖。那麼以下圖所示,Mode就是模型的Prefab文件,那麼我僅僅只須要把Mode這個預設打包成Assetbundle便可。 當我在服務器上下載這個Assetbundle而且載入遊戲中就能夠直接使用了,切換動畫、換貼圖均可以。。ide

Unity3D研究院之Assetbundle的原理(六十一) - 雨鬆MOMO程序研究院 - 1

2.二進制文件工具

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

 3.場景文件動畫

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

4.移動平臺

        上面MOMO已經將Assetbundle 的使用原理大體介紹了一下 ,咱們在談談移動平臺。腳本不能更新是移動平臺下最大的傷,這就意味着開發者沒法繞過App store和 google Play這種在線商店升級應用程序。惟一能作到的就是更新資源、舉個例子,遊戲中在處理版本升級時,通常會有個大版本號和一個小版本號,大版本號就是 2.0、3.0這種 版本須要在AppStore中更新,大版本主要是升級遊戲腳本,而後當小版本號,好比2.0.1 或2.0.2這種只是更新遊戲中的資源,經過本身遊戲的服務器就能夠完成,經過Assetbundle在本身服務器上下載,而後適應在遊戲中。若是非要更新腳本,或不得不更新腳本那麼只能在Appstore或者google Play去更新大版本。

    移動平臺上不能更新腳本,那麼Prefab上綁定的腳本怎麼辦?在任何平臺上均可以把腳本添加到Prefab上,而後打包成Assetbundle,只有移動平臺上有點特殊,好比將Test.cs這條腳本綁定在Prefab中,最後程序經過服務器下載這個Assetbundle ,當載入工程中這條腳本是不會被執行的。

          可是若是本地工程有Test.cs這條腳本,那麼Unity會自動將這條腳本綁定在下載的Prefab中,而且他們執行的很是好。若是本地工程中沒有Test.cs這條腳本,那麼Prefab上的腳本是永遠都不會執行的。有時咱們會在腳本中寫一些Public的變量,有可能不一樣的Prefab上綁定的是相同的腳本,只是Inspector 腳本中的public參數不一樣。別擔憂這一點Assetbundle 中的Prefab也是沒問題,因此說只要大版本中的腳本沒問題,在小版本中只更新遊戲資源是一點問題都麼有的。

5.移動優化

        以前咱們說過能夠將遊戲中的某個遊戲對象封裝成Assetbundle,也能夠將遊戲中的整個場景也封裝成Assetbundle。可是我認爲須要巧妙的使用封裝場景,由於場景中確定有不少公用的模型,若是打包場景的話那麼內存與size就是 公用模型的size * N個場景,想一想其實挺恐怖的。其實咱們能夠巧妙的使用,首先把場景中公用的部分和私有的部分通通放入Unity, 而後烘培整個場景。 當場景烘培完畢後把公用的模型部分在拿出去,場景只只保留私有的模型。還能夠作一個工具將公用模型在場景中的座標保存在XML中(每一個場景文件會對應一個公用模型的XML信息),最後在將公用的模型分別封裝在別的Assetbundle中。

       服務器上提供每一個場景的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 是能夠轉換成 字節數組 ,客戶端與服務器約定一組解密 字節數組的算法就能夠實現資源加密。

大版本升級: 

unity的版本升級其實主要是升級主程序中的腳本。 由於全部的資源都是assetbundle 和 .unity3d   這些資源放在本地或者服務器 解包的方式是徹底同樣,因此理論上咱們的主程序包的大小能夠作到很小,能夠很好設置把多少資源放在包裏 或者把所少資源放在服務器上。在運行的時候服務端應該把全部 assetbundle 和 .unity3d的資源文件的下載地址列表返回給客戶端。

小版本升級:

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

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

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

 

由於Assetbundle這塊的代碼比較多,我仍是決定分紅兩篇文章來寫,這篇文章先說原理、下篇文章說代碼。歡迎你們來討論!

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

 

相關文章
相關標籤/搜索