1. 程式人生 > >【Unity】資源打包AssetBundle的概念和流程

【Unity】資源打包AssetBundle的概念和流程

估計很多人只知道Unity的模型之類的東西可以匯出成一種叫做AssetBundle的檔案,然後打包後可以在Unity程式執行的時候再載入回來用。那麼AssetBundle是一個什麼樣的東西呢?其實AssetBundle只是一種使用LZMA壓縮方式壓縮的資原始檔。具體LZMA是什麼請百度,你可以理解成就是一種壓縮檔案就行了,至於它的字尾名是什麼,一點關係都沒有,你可以自己定。AssetBundle打包的時候,你可以指定一個mainAsset,那麼載入完之後就可以通過AssetBundle.mainAsset來獲取到了。你也可以不指定mainAsset,直接打包一堆內容進去,然後載入後通過AssetBundle.LoadAsset指定名字的讀取出來。在資源之間,存在著依賴的關係。你可以把資源拆分得很細,比如一個模型,由網格模型、材質、貼圖構成,你可以把每一個小部分都拆開,各自打包成壓縮檔案。當Unity需要載入使用的時候,把該模型的所有依賴的小資源都載入起來,然後根據依賴關係組裝,就變回了我們看到的資源了。

二、AssetBundle的依賴結構

要說明依賴關係結構,我們還是使用上面的例子,一個模型,分為了網格模型、材質、貼圖。那麼他們是怎樣依賴的呢?然後在Unity5的打包裡面,他們是怎樣表現出依賴關係的呢?接下來做一個小小的實驗:我準備了4張貼圖,分別叫做t1、t2、t3、t4,然後建立了兩個材質球,分別是m1、m2,m1材質使用了t1、t2、t3三張貼圖,m2材質使用了t4貼圖。


最後建立兩個模型,我就使用unity內建的模型了。obj1是一個cube,obj2是一個quad。obj1使用了m1材質,obj2使用了m2材質。然後obj1和obj2都做成了預設,放在了Assets/Resources/Obj/下面


那麼現在他們的結構應該是這樣的:


接下來,先只設置obj1的assetBundleName,然後匯出


匯出之後,我們看看AssetBundle.manifest裡面只有一個Info,就是剛才我們命名的obj1.ab,而obj1.ab下面的Dependencies是空的,也就是它沒有任何依賴了。再看看obj1.ab.manifest


裡面包含了型別的雜湊碼、Assets資源的路徑,和依賴。這裡它的依賴還是空的。

接下來把obj2也賦予AssetBundleName:


再匯出,會發現除了剛才的檔案以外,會多了2個檔案,就是obj2.ab和obj2.ab.manifest。
還是開啟AssetBundle.manifest看看,會發現這次的

Info變成了2個,分別是obj1.ab和obj2.ab

開啟obj1.ab.manifest


發現和剛才沒什麼變化。再看看obj2.ab.manifest


它的結構和obj1.ab.manifest差不多。
剛才只是把2個模型設定了匯出AssetBundle,接下來我會把兩個材質和四張貼圖都設定匯出不厭其煩的把圖貼上來:



這時候匯出,我們的所有依賴關係都應該存在了。匯出之後,多了很多檔案,是這樣的: 再來看AssetBundle.manifest


這次看到的Info有7個了,其實我們設定了多少個AssetBundleName匯出,它就應該有多少個Info。
obj1.ab.manifest


這次看到它的Dependencies,會看到有依賴了,寫的是一個本地的地址。有人會說,這個絕對路徑有問題啊,我把這個檔案放到cdn上面,路徑就會不對啊。這個先不急,下面會說明是什麼回事。
m1.ab.manifest


會發現結構差不多,但依賴列表裡面會有三個地址,就是我們三張貼圖的地址了。
obj2.ab.manifest 和 m2.ab.manifest情況會差不多


接下來,要做最後一步試驗了,比如剛才我已經是整個專案的匯出了,現在我突然需要改動其中的一個小部分,現在我就把t4不匯出了。

那麼現在我們再整個專案的AssetBundle匯出,會怎樣?匯出完之後,看目錄,會發現檔案和剛才是一樣多的,t4.ab並沒有被刪掉。再看AssetBundle.manifest


Info變成6個了,而裡面某些項的依賴列表變了看obj1.ab.manifest

和剛才沒有變化
obj2.ab.manifest


和剛才也是沒有變化的看m2.ab.manifest

這裡的依賴列表沒有了。
這其實就是AssetBundle的鏈式結構和增量打包了。一個小的部分改變了,它將會改變的地方只有總的AssetBundle.manifest,還有直接依賴於它本身的manifest。其他不依賴的部分是不需要重新打包的。還有一點需要注意的地方是,除了manifest檔案以外,還有一個沒有後綴名稱的AssetBundle檔案。這個檔案其實才是包含了所有的依賴關係的總的依賴關係配置檔案,剛才我們能用txt開啟的manifest檔案,都只是用來做本地依賴關係和增量打包的時候用的。我們載入AssetBundle的時候,完全不需要載入那些manifest檔案的,只需要那個沒有後綴名稱的AssetBundle檔案(具體名字和你匯出的資料夾有關)就行了,它代表的是該專案的所有AssetBundle的依賴關係。所以,剛才我們看到manifest裡面用的都是本地的絕對路徑,那是針對你本地打包時用的,和載入無關。  

三、匯出AssetBundle和自動設定名稱

剛才我們都是直接的輸入AssetBundleName來匯出AssetBundle的,其實這一步可以使用程式碼自動完成在Unity專案內部,每一個小的資源(網格、材質、貼圖、聲音等),都會有一個唯一的雜湊Id的,是一串很長的字母和數字組合。我們可以通過AssetDatabase.AssetPathToGUID來獲得這個ID。那麼自動設定就變得簡單了,可以通過以下的程式碼,我們可以設定一個總的prefab的AssetBundleName,然後自動獲得它身上的所有依賴,然後獲得每個依賴資源的唯一Id,再賦予AssetBundleName就行了


四、載入AssetBundle的步驟

通過上面匯出AssetBundle的說明,估計現在想要把它載入起來就變得簡單了。首先需要明白一個規則,資源的依賴關係組裝是unity本身會自動完成的。比如一個資源A,它是依賴於資源B和資源C的,那麼如果我們需要載入資源A進來並正確的顯示出來,我們必須先把資源B和資源C載入,然後再載入資源A。當資源A載入進來之後,發現記憶體裡面已經有資源B和資源C了,它會自動的組裝起來。那麼再看看載入的步驟了:1、獲得總的依賴配置剛才已經說明了,真的有用的依賴配置檔案是沒有後綴名稱的AssetBundle檔案,所以我們需要載入的就是這個檔案了。string mUrl = Cdn + "AssetBundle";然後www載入。之後很多人看不懂,說我這個Cdn是什麼東西,“AssetBundle”又是什麼東西,現在應該明白了吧?Cdn就是你的資源伺服器路徑,“AssetBundle”就是檔名,它沒有後綴,具體的名字是和你匯出的資料夾一樣的。載入後,通過AssetBundle.LoadAsset("AssetBundleManifest"),就可以把剛才那個沒有後綴名的檔案轉成AssetBundleManifest物件mainfest。2、根據名稱找到目標載入資源的所有依賴獲得了AssetBundleManifest物件mainfest之後,比如我們實際上是需要載入obj1.ab的,這在剛才的AssetBundle.manifest裡面可以知道,它的Info裡面就有obj1.ab。然後我們通過string[] dps = mainfest.GetAllDependencies("obj1.ab");就可以獲取到obj1.ab的所有依賴了,包括了子依賴,比如它依賴於m1.ab,然後m1.ab依賴於t1.ab、t2.ab、t3.ab,那麼這裡獲取到的就應該是4個依賴了。分別是m1.ab、t1.ab、t2.ab、t3.ab。3、載入所有依賴的資源獲取到obj1.ab的所有依賴之後,就應該逐個的去載入他們了。分別www載入他們,然後儲存他們的AssetBundle。4、載入目標載入資源當載入了所有的依賴資源之後,就可以光明正大 的去載入目標資源了,這裡我們的目標資源就是obj1.ab。5、例項化顯示obj1.ab載入完之後,你愛怎樣用都可以,直接例項化出來吧。


由於AssetBundle是不能重複載入的,如果你需要多次載入一個資源,你有2個選擇,要麼載入了就Unload(false)解除安裝了它。要麼你可以把它存起來,當需要相同名字的AssetBundle的時候,直接取出來。

五、最後的建議

1、Unity5的新版AssetBundle好像是一套全新的系統,其實和舊系統的差別並沒有很大,只是自動生成了依賴配置檔案而已。這一個步驟實際上完全可以自己實現的,那些配置檔案可以用自己喜歡的格式生成,然後載入的時候再自己想辦法把依賴關係找回來就行了。2、個人覺得把AssetBundle拆得太碎並不是一件好事情。為什麼這麼說呢?用過電腦的人都知道,拷貝檔案的時候是一個個碎的檔案拷貝快?還是把一堆檔案壓縮成一個包,然後拷貝快?如果載入一個模型,需要分別載入十幾次依賴資源,才能顯示,這個過程中傳送這麼多的www或者http請求,過程有點危險。至於說冗餘檔案的問題,自己考慮一下分佈策略吧。2、 一般來說,這種東西都需要配合著一套資源管理的系統來用的,所以在上一篇部落格裡面,我只是介紹新AssetBundle的特性,不太可能整一套系統都搬出來,只寫了幾句有代表性的關鍵方法當做虛擬碼來說明。結果很多人要麼就說亂,要麼就說有錯誤。其實說來說去,就是自己沒搞懂原理,又急著拿別人的程式碼來用……做人還是踏實一點的好。 


相關推薦

Unity資源打包AssetBundle概念流程

估計很多人只知道Unity的模型之類的東西可以匯出成一種叫做AssetBundle的檔案,然後打包後可以在Unity程式執行的時候再載入回來用。那麼AssetBundle是一個什麼樣的東西呢?其實AssetBundle只是一種使用LZMA壓縮方式壓縮的資原始檔。具體LZMA是什麼請百度,你可以理解成就是一種

Solr入門之概念安裝

   Apache Solr 是Apache Lucene專案的開源企業搜尋平臺。其主要功能包括全文檢索、命中標示、分面搜尋、動態聚類、資料庫整合,以及富文字(如Word、PDF)的處理。Solr是高度可擴充套件的,並提供了分散式搜尋和索引複製。Solr是最流行的企業級搜尋引擎,Solr

資料庫遊標的概念作用

1遊標和遊標的優點    在資料庫中,遊標是一個十分重要的概念。遊標提供了一種對從表中檢索出的資料進行操作的靈活手段,就本質而言,遊標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制。遊標總是與一條SQL 選擇語句相關聯因為遊標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結

UnityUnity5版本的AssetBundle打包方案之資源打包

using UnityEngine; using System.Collections; using UnityEditor; /// <summary> /// 指令碼位置:Editor

UnityUnity資源池的動態載入釋放記憶體優化處理

需求環境         在上一級的【解決方案】文章中,我們設計出了動態載入資源的業務流程,而這一節,我們就通過一些簡單的程式碼,來實現出業務流程中的效果。        吸取之前文章的經驗,如

Unity打包安卓APK常見問題

pos 記得 () dex text player call ces efault 問題:unity error invalid command android 原因:Android版本較新,Unity版本太舊(如4.X),Unity打包APK時調用Android工具使用的

待修改[HDFS_1] HDFS 的概念特性

  0. 參考     HDFS你一定要知道,要考的   大資料開發實戰:HDFS和MapReduce優缺點分析   SecondaryNamenode的作用詳解     1. HDFS 是什麼    HDFS :一種分散式檔案系統,

Unity多平臺自定義巨集Scripting Define Symbols的使用

平臺定義 UNITY_EDITOR 編輯器呼叫。 UNITY_STANDALONE_OSX 專門為Mac OS(包括Universal,PPC和Intelarchitectures)平臺的定義。 UNITY_DASHBOARD_WIDGET Mac OS Dashboard

Unityios平臺匯出Xoce專案打包成ipa過程(圖文詳盡版)

按照下面的步驟走,就可以打包成功,我不說各種原因,只講操作步驟:簡單粗暴!!!首先你得有一個蘋果開發者賬號。要是沒有,就自己申請一個。注意:在建立app IDs 還有描述檔案的時候,需要新增的是釋出版本,就是ad hoc裡面的版本,而不是簡單的開發版本。如下圖:(證書與描述檔案都需要釋出版本的)可以先忽略,一

UnityUnity資源動態載入的兩種方式之AssetsBundle

首先要說的是,我們的工程中有2個指令碼,分別是:Build(編輯器類指令碼,無需掛載到任何物體),但是必須要把Build指令碼放到Editor資料夾中Load指令碼,掛載到攝像機上<pre name="code" class="csharp">using Uni

Unity用NGUI實現血條傷害顯示

using UnityEngine; using System.Collections; public class create_HP : MonoBehaviour {     public GameObject HP_prefab;  //預設的血條     public Transform create

整理1、C網G網雙模手機是否可同時支援C網G網上網?2、上網的同時是否可以打電話?3、呼叫等待呼叫保持的概念與“雙通”手機

【問題一】C網和G網雙模手機是否可同時支援C網和G網上網? 這個以華為的兩款手機為例,華為出了兩款雙模手機:S8600和G330C(C8825D),這兩款手機均是C網和G網雙模,支援電信的3G網,只支援移動(聯通)的2G網,且手機預設是隻支援C網上網的。 那麼S8600和G

爬蟲Python Scrapy 基礎概念 —— 請求響應

Typically, spiders 中會產生 Request 物件,然後傳遞 across the system,  直到他們到達 Downloader, which 執行請求並返回一個 Response 物件 which travels back to the

UnityUnity 打包Player Settings匯出設定

轉載地址:http://blog.csdn.net/highning0007/article/details/37991321 播放器設定是將在Unity中編譯最終遊戲時定義的各種引數(特定平臺)的地方。當開啟獨立版遊戲,啟動時例如使用在解析度對話方塊的這些值,當編譯i

UnityFBXPrefab 同名造成的問題

在專案中 動態載入一物體時,載入預設體生成出來的物體身上沒有預設體身上的元件 後來發現 問題  由於動態載入是找的名字 所以當你Fbx 和prefab 名字 相同時 會產生找的 可能是你的 FB

unityunity自動化打包——利用XUPorter解決xcode8問題

unity自動化打包有一個很好用的外掛,XUPorter。 本文所有問題都是利用XUPorter解決。當然還有其他方法,但是我懶。 XUPoter的原理就不多說了。直接進正題。 1.關於Automatically manage signing 此為Xco

Unityios平臺IAP內購沙箱測試流程詳解(開發中遇到的坑)

Unity iOS內購 內購流程 1、在 AppStore 中建立相應的物品,建立內購沙盒測試賬號2、客戶端從後臺獲取相應的物品 ID (當然也可以再客戶端寫死,但後期擴充套件性就受限制了)3、依據相應的物品 ID 請求商品的相關資訊4、依據商品資訊建立訂單請求交易5

轉載Hadoop 2.7.3 Hbase 1.2.4安裝教程

啟動 運行 property new rop net 文本文 .tar.gz cor 轉載地址:http://blog.csdn.net/napoay/article/details/54136398 目錄(?)[+] 一、機器環境

bzoj3261最大異或

異或 ... urn fin pri bit names -- else 就是一個可持久化Trie....... #include<bits/stdc++.h> #define N 600005 using namespace std; inline int

C字符串常量字符數組

gcc pre class fun 後者 一段 put light cmp 此次博客是轉載某位博主的文章,不過現在找不到了,所以先聲明一下。 先貼一段代碼: #include <stdio.h> int main(int argc, const char**