Unity3D中assetbundle格式的示例分析

這篇文章將為大家詳細講解有關Unity3D中assetbundle格式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)公司主要從事成都做網(wǎng)站、網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務崗巴,十余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:028-86922220

Unity3D 的 asset bundle 的格式并沒有公開。但為了做更好的差異更新,我們還是希望了解其打包格式。這樣可以制作專門的差異比較合并工具,會比直接做二進制差異比較效果好的多。因為可以把 asset bundle 內(nèi)的數(shù)據(jù)拆分為獨立單元,只對變更的單元做差異比較即可。

網(wǎng)上能查到的資料并不是官方給出的,最為流行的是一個叫做 disunity 的開源工具。它是用 java 編寫的,只有源代碼,而沒有給出格式說明(而后者比代碼重要的多)。通過閱讀 disunity 的代碼,我整理出如下記錄:


asset bundle 分為壓縮模式和非壓縮模式。壓縮模式僅僅是用開源的 lzma 庫 對整個非壓縮包做了一次整體壓縮。壓縮數(shù)據(jù)的頭有 13 個字節(jié),前 5 個字節(jié)是 lzma 解壓縮的 API 需要穿入的 props ,接下來的 4 字節(jié)是解壓縮后的數(shù)據(jù)庫長度。最后 4 字節(jié)不用理會它。

把壓縮數(shù)據(jù)解開后,就和非壓縮模式?jīng)]有差別,下面只討論非壓縮格式:

assert bundle 的文件頭是從這樣一個數(shù)據(jù)結構序列化出來的。

struct AssetBundleFileHead {
     struct LevelInfo {
          unsigned int PackSize;
          unsigned int UncompressedSize;
     };

     string          FileID;
     unsigned int     Version;
     string          MainVersion;
     string          BuildVersion;
     size_t          MinimumStreamedBytes;
     size_t          HeaderSize;
     size_t          NumberOfLevelsToDownloadBeforeStreaming;
     size_t          LevelCount;
     LevelInfo     LevelList[];
     size_t          CompleteFileSize;
     size_t          FileInfoHeaderSize;
     bool          Compressed;
};

string 是直接以 \0 結尾的字符串,順序序列化;size_t 是大端的 4 字節(jié)數(shù)字;bool 是單個字節(jié);vector 就是順著排列的結構。

根據(jù) Unity 版本的不同,assert bundle 的格式也不完全相同。Version 指明了 bundle 的格式版本,從 Unity 3.5 開始到 4.x 版都使用 Version = 3 ,下面只討論這個版本。HeaderSize 應該恰好等于以上這個文件頭的數(shù)據(jù)長度。

一個 assert bundle 是由多個 asset 文件打包而成,接下來順序打包了這些 asset 。序列化成這樣的結構:

struct AssetFileHeader {
     struct AssetFileInfo {
          string name;
          size_t offset;
          size_t length;
     };
     size_t FileCount;
     AssetFileInfo     File[];
};

這樣我們就可以分解出被打包在一起的多個 Asset 了(大多數(shù)情況下只有一個)。offset 表示的是除去 HeaderSize 后的偏移量。我們可以用 HeaderSize 加上那個部分的 offset 得到這個部分相對于整個 bundle 的文件偏移。

對于每個 asset ,又有它自己的數(shù)據(jù)頭。數(shù)據(jù)頭除了基本的數(shù)據(jù)頭結構 AssetHeader 外,還有額外的三個部分。disunity 把它們稱為 TypeTree ObjectPath 和 AssetRef 。注意:這里 Format 隨不同 Unity3D 的版本有所不同,我們只關心目前的版本的格式,這里 Format 為 9 (其它版本的格式,在大小端等問題上有所不同)。

struct AssetHeader {
     size_t TypeTreeSize;
     size_t FileSize;
     unsigned int Format;
     size_t dataOffset;
     size_t Unknown;

Unity 對 Asset 數(shù)據(jù)做了簡單粗暴的序列化操作。整個序列化過程是針對每種對象的數(shù)據(jù)結構進行的。TypeTree 是對數(shù)據(jù)結構本身的描述,通過這個描述,就可以反序列化出每個對象。

AssetHeader 后面緊跟著的就是 TypeTree 。但是,這個 TypeTree 對于 asset bundle 來說是可選的,因為數(shù)據(jù)結構的信息可以事先放置在引擎中(引擎多半只支持固有的數(shù)據(jù)類型)。在發(fā)布到移動設備上時,TypeTree 是不打包到 asset bundle 中的。

每個 asset 對象,都有一個 class id ,可以在 TypeTree 中查到如何反序列化。class id 的和具體類型的對應關系,在 Unity3d 的官方文檔 可以查到。但若我們只是想將差異比較在對象一級進行(而不是具體比較對象中具體的屬性),那么就不需要解開具體對象的細節(jié)信息,這部分也不用關心。所以這里也不展開(有興趣可以讀一下 disunity 的代碼,格式并不復雜)。

在 AssetHeader 中的 TypeTreeSize 指的就是 TypeTree 部分的大小。接下來是每個 AssetObject 的描述數(shù)據(jù)。

struct ObjectHeader {
     struct ObjectInfo {
          int pathID;
          int offset;
          int length;
          byte classID[8];
     };
     int ObjectCount;
     ObjectInfo Object[];
};

這里,所有的 int 都是以小端編碼的 4 字節(jié)整數(shù)(不同于外部文件格式采用的大端編碼)。在 Unity3D 中,每個對象都有唯一的字符串 path ,但是在 asset bundle 里并沒有直接保存字符串,而是一個 hash 過的整數(shù),也可以看成是對這個對象的索引號。真正的對象放在數(shù)據(jù)頭的后面,偏移量為 offset 的地方。

這里的 offset 是相對當前 asset 塊的。如果想取得正確的相對整個文件的位置,應該是文件的 HeaderSize + asset 的 offset + asset 的 dataOffset + 這里的 object offset 。


接在 ObjectHeader 后的是 AssetRef 表,記錄了 Asset 的引用關系。用于指明這個 bundle 內(nèi) asset 對外部 asset 的引用情況。AssetRefTable 結構如下:

struct AssetTable {
     struct AssetRef {
          byte GUID[8];
          int type;
          string filePath;
          string assetPath;
     };
     int Count;
     byte Unknown;
    vector Refs;本文分享自微信公眾號 - Unity3D游戲開發(fā)精華教程干貨(u3dnotes)。

關于“Unity3D中assetbundle格式的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

本文名稱:Unity3D中assetbundle格式的示例分析
網(wǎng)頁URL:http://muchs.cn/article26/ijcdjg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設搜索引擎優(yōu)化、定制網(wǎng)站網(wǎng)站設計公司、全網(wǎng)營銷推廣、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名