一.AssetBundle的概念
“AssetBundle”可以指兩種不同但相關的東西。
1.1 AssetBundle指的是u3d在磁盤上生成的存放資源的目錄
目錄包含兩種類型文件(下文簡稱AB包):
- 一個序列化文件,其中包含分解為各個對象并寫入此單個文件的資源。
- 資源文件,這是為某些資源(紋理和音頻)單獨存儲的二進制數據塊,允許 Unity 高效地在另一個線程上從磁盤加載它們。
1.2 AssetBundle可以指在代碼層面,AssetBundle這個類的對象
該對象包含添加到此存檔文件的資源的所有文件路徑的映射。
二.AssetBundle的作用
- 更新非代碼資源
- 減少安裝包大小
- 加載最終用戶平臺優化的資源
三.AssetBundle 工作流程
3.1?為 AssetBundle 分配資源
1.選中資源
2.Inspector中底部點開下拉選單
3.點擊New
4.輸入目錄/文件名
5.輸入后綴
3.2?構建 AssetBundle
在 Assets 文件夾中創建一個名為 Editor 的文件夾,并將包含以下內容的腳本放在該文件夾中:
using UnityEditor;
using System.IO;
public class BuildAssetBundle
{[MenuItem("Assets/Build AssetBundles")]static void BuildAllAssetBundles(){string assetBundleDirectory = "Assets/AssetBundles";if (!Directory.Exists(assetBundleDirectory)){Directory.CreateDirectory(assetBundleDirectory);}BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);}
}
此腳本將在 Assets 菜單底部創建一個名為?Build AssetBundles?的菜單項,該菜單項將執行與該標簽關聯的函數中的代碼。單擊?Build AssetBundles?時,將隨構建對話框一起顯示一個進度條。此過程將會獲取帶有 AssetBundle 名稱標簽的所有資源,并將它們放在?assetBundleDirectory
?定義的路徑中的文件夾中。
3.3 加載依賴項
依賴關系:一個AB包的資源包含了對另一個AB包資源的引用,如上圖中的cube1包中的cube引用了blue包中的材質,稱cube1包依賴blue包
打包時unity會自動識別出包的依賴關系,并記錄到AB包的manifest文件中,如下圖所示
小結:如果a包依賴b包,在使用a包資源之前,務必加載b包,Unity不會自動加載依賴項。
3.4 AssetBundle的加載和使用
1.調用AssetBundle.LoadFromFile加載AB包并獲取對象
2.調用LoadAsset從獲取該包內的資源
using UnityEngine;public class LoadAssetBundle : MonoBehaviour
{void Start(){//依賴的材質也需要加載AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/material/blue.u3d");AssetBundle myLoadedAssetBundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/prefabs/cube1.u3d");GameObject prefab = myLoadedAssetBundle.LoadAsset<GameObject>("Cube");Instantiate(prefab);}
}
四.通過AssetBundles.manifest文件獲取依賴關系
位于AssetBundles根目錄下的AssetBundles.manifest是個文本文件,包含了所有AssetBundle包的信息和依賴關系,如下圖所示
AssetBundles.manifest的信息可以通過代碼訪問
using UnityEngine;public class LoadAssetBundle : MonoBehaviour
{void Start(){AssetBundle myLoadedAssetBundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/prefabs/cube1.u3d");loadDependency();GameObject prefab = myLoadedAssetBundle.LoadAsset<GameObject>("Cube");Instantiate(prefab);}private void loadDependency(){AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/AssetBundles");AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//傳AssetBundleManifest這個文件固定名稱string[] dependencies = manifest.GetAllDependencies("prefabs/cube1.u3d");foreach (string dependency in dependencies){Debug.Log(dependency);AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/" + dependency);}}
}