說明
本系列所使用unity版本為5.3.4f1。
AssetBundle簡介
AssetBundle是Unity Pro提供和推薦的資源導出方式,它可以把多個自定義的游戲對象或者資源以二進制形式保存到Assetbundle文件中。Assetbundle支持所有unity可識別的格式:模型、貼圖、音頻、整個場景等,其中最為方便的是可以將關聯的內容制作成一個prefab,例如一個模型的貼圖、動作和模型等,然后將整個prefab導出到AssetBundle,即可保留prefab中資源和腳本之間相互關聯。
AssetBundle內部格式
-
以下圖來自官網,黑體為翻譯。
一個AssetBundle本質上是將一些對象組合成一個序列化文件,根據是普通bundle(normal bundle)還是場景bundle(scene bundle),Assetbundle可以展開成略有不同的數據文件。
normal bundle
scene bundle
后面會詳細講到其內部格式,現在可以看到,普通的AssetBundle包含了本身信息(Assetbundle)、各個對象和音頻文件,而場景Assetbundle還包含了預加載數據(PreloadData)、shaderData和全局光照數據(Global Illumination Data)。
壓縮
AssetBundle可以選擇是否壓縮,Unity5.3之前只能使用LZMA壓縮,Unity5.3之后支持選擇LZ4壓縮。
圖中壓縮部分顯示了可能有塊壓縮(chunk-based)和流壓縮(stream-based)兩種方式。塊壓縮(LZ4)指的是原始數據被分成大小相同的子塊並單獨壓縮。如果你想要實時解壓/隨機讀取開銷小,則應該使用這種。而流壓縮(LZMA)在處理整個數據塊時使用同一個字典,它提供了最大可能的壓縮率但只支持順序讀取。
LZMA壓縮方式的優點在於AssetBundle壓縮率較高,但只能順序讀取意味着加載任意一個資源時,都需要將整個AssetBundle解壓,造成卡頓和額外內存占用。LZ4壓縮率較低(測試LZMA換LZ4:86.9M -> 108M),但不需要全部解壓即可讀取,不會有大的卡頓和額外內存占用。后面會詳細對比兩種壓縮方式。
AssetBundle內部格式
這里有一篇Unity3D asset bundle 格式簡析,分析了unity3.5下Assetbundle的內部格式,總結下來結構如下:
- AssetBundleFileHead : 記錄了版本、是否壓縮等主要描述信息。
- AssetFileHeader :包含一個文件列表,記錄了每個資源的name,offset,length等。
- Asset1 : 第一個資源本身,內部結構如下
- AssetHeader :包含了TypeTree大小、文件大小、format等。
- TypeTree(可選):記錄了asset 對象的class id,在 Unity3d 的官方文檔 可以查到每個id的對象。
- ObjectPath :主要記錄了一個pathID(資源唯一索引id)。
- AssetRef:記錄了AssetBundle對外部資源的引用情況。
- Asset2 :第二個資源,結構跟上面一樣
- ……> : 更多資源
大致符合官網上normal bundle的內容,看來Unity在方面變動不大,文中也提到了分析方式是閱讀disunity源碼,而disunity也已經支持了unity5,有興趣也可以分析unity5中Assetbundle的內部結構。