2026.6.7 - AB包学习(1)

完成了什么

分别用三种方式加载 AB 包中的资源:

  1. 普通同步加载:最简单的用法,直接加载单个 AB 包中的资源

  2. 依赖加载:处理 AB 包之间的依赖关系,分两种写法

  3. 异步加载:运行时动态加载,避免卡顿

示例资源:一个 AB 包里包含BulletCylinder两个预制体。


一、普通同步加载

LoadPath = Application.streamingAssetsPath; // 加载 AB 包文件 AssetBundle ab = AssetBundle.LoadFromFile(LoadPath + "/" + "model"); // 从 AB 包中加载资源 GameObject go = ab.LoadAsset<GameObject>("Bullet"); GameObject go2 = ab.LoadAsset<GameObject>("Cylinder"); // 实例化到场景 Instantiate(go); Instantiate(go2);

关键点:

  • LoadFromFile从磁盘文件加载 AB 包,同步执行,会卡主线程

  • LoadAsset<T>从已加载的 AB 包中获取指定名称的资源

  • 适合启动时加载(配合 Loading 界面)或小文件


二、依赖加载

当 AB 包之间有依赖关系时(比如model包引用了material包里的材质),需要先加载所有依赖包,否则资源会丢失材质或贴图。

写法一:加载全部依赖(简单粗暴)

// 加载主包(Manifest 包) AssetBundle abMain = AssetBundle.LoadFromFile(LoadPath + "/" + "StandaloneWindows"); // 获取 Manifest AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); // 获取所有 AB 包名称 string[] depNames = abManifest.GetAllAssetBundles(); // 全部加载 foreach (string depName in depNames) { AssetBundle.LoadFromFile(LoadPath + "/" + depName); }

适用场景:资源数量少、不在乎加载时间。

写法二:只加载指定包的依赖(推荐)

// 获取 "model" 这个包依赖了哪些包 string[] deps = abManifest.GetAllDependencies("model"); // 只加载这些依赖 foreach (string depName in deps) { AssetBundle.LoadFromFile(LoadPath + "/" + depName); }

适用场景:AB 包数量多,只想加载当前需要的包及其依赖,节省内存。

两种写法的区别:

GetAllAssetBundlesGetAllDependencies
加载范围所有 AB 包指定包的依赖
内存占用
适用场景小项目、全量预加载大项目、按需加载

三、异步加载

运行时加载资源,不想卡主线程,就用异步。

IEnumerator ABAsyncLoad(string path) { // 异步加载 AB 包文件 AssetBundleCreateRequest abAsync = AssetBundle.LoadFromFileAsync(path); yield return abAsync; // 等待加载完成,主线程不卡 AssetBundle bundle = abAsync.assetBundle; if (bundle == null) { Debug.LogError("Failed to find AssetBundle"); yield break; } // 从包中同步加载资源(此时包已在内存中,速度很快) GameObject prefab = bundle.LoadAsset<GameObject>("Bullet"); if (prefab != null) { Instantiate(prefab); } } // 调用 StartCoroutine(ABAsyncLoad(LoadPath + "/" + "model"));

关键点:

  • LoadFromFileAsync返回AssetBundleCreateRequest

  • yield return等待加载完成,不阻塞主线程

  • AB 包加载完成后,内部资源的LoadAsset用同步方式即可,因为文件已在内存中

什么时候用异步:

场景推荐方式
启动时加载同步(反正有 Loading 界面)
运行时换武器、切场景异步(不能卡玩家操作)
加载大文件(>10MB)异步
加载小配置文件同步

四、卸载

AssetBundle.UnloadAllAssetBundles(false);

参数区别:

  • false:只卸载 AB 包本身,已加载的资源(预制体、贴图等)保留

  • true:连同所有已加载的资源一起卸载

什么时候用:

  • 切换场景时调用UnloadAllAssetBundles(true)彻底清理

  • 只想释放 AB 包内存,但资源还要用,用false


五、总结

加载方式方法特点
同步加载LoadFromFile简单,会卡主线程
异步加载LoadFromFileAsync不卡主线程,配合协程
依赖加载GetAllDependencies按需加载依赖,省内存
卸载UnloadAllAssetBundles释放 AB 包内存