一、简介

Unity的AssetBundle(简称AB包)。是Unity提供的一种资源打包机制,可以把模型、贴图、音频、预制体等资源打包成一个或多个 “包” 文件。运行时可以通过代码动态加载。

需求场景:

  • 减小首包体量:游戏只需下载启动必需资源,后续按需下载

  • 热更新:无需重新提交应用商店,即可修复bug或更新内容

  • 降低内存:可主动卸载不再使用的AB包,释放内存

  • 按需加载:例如进入特定关卡才下载该关卡的美术资源

(总结就是:AB包 做游戏必备,闭眼入就对了)


二、Unity中打AB包,实际流程:

1、标记资源

  • 在Inspector底部可以为每个资源指定AB包名,相同包名标记的资源,会打为一个包中


2、打包

  • 使用 Asset Bundle Browser 打包: (Windows  >  Asset Bundle Browser  >  Build )
  •        

Asset Bundle Browser 安装方法:

包管理 —> Git安装:https://github.com/Unity-Technologies/AssetBundles-Browser.git

如果用包管理安装不上,直接在Github下载(删除Tests文件夹)放Unity

一个AB包通常包含两部分:

  1. 主包 文件:包含所有资源

  2. Manifest 文件:包含了包中资源依赖其他包的信息


3、用代码加载

 AssetBundle bundle = AssetBundle.LoadFromFile("包文件路径");
// 加载具体资源
 var prefab = bundle.LoadAsset<资源类型>("包中的资源名称");


// 假如是游戏对象(GameObject),需要克隆一下,才能出现在场景

// Instantiate(prefab); 


三、常见问题

1、冗余问题

  • 问题:多个AB包中 - 都包含相同资源

  • 举例:例如 资源A和B都引用了C,但A和B被打入了不同的AB包,而C没有归属于任何一个AB包。这种情况下,A包和B包会各自包含一份C的副本,造成冗余。

  • 解决:将共用资源单独打包(如shared_shader包),其他包依赖它

2、依赖管理

  • 问题:AB包之间常存依赖关系,若不加管理,容易因依赖缺失而导致引用丢失。

  • 举例例如 加载包A中的资源a时,若a引用了包B中的资源b,且包B尚未被加载,则会导致资源a的引用丢失。

  • 解决:加载AB包前,用Manifest获取所有依赖并先加载

  • 示例代码:

IEnumerator LoadAssetBundle()
{
    // 1. 加载本地或远程的Manifest文件
    AssetBundle manifestAB = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "StreamingAssets"));
    AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    
    // 2. 获取依赖关系(重要:必须先加载依赖)
    string[] dependencies = manifest.GetAllDependencies(bundleName);
    foreach (string dep in dependencies)
    {
        yield return StartCoroutine(LoadBundle(dep));
    }
    
    // 3. 加载目标AB包
    AssetBundle bundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, bundleName));
    
    // 4. 加载具体资源
    GameObject prefab = bundle.LoadAsset<GameObject>("MyPrefab");
    Instantiate(prefab);
    
    // 5. 可选:卸载AB包
    // bundle.Unload(false); // 只卸载AB包,已加载的资源保留
}

3、内存泄露

  • 可能的原因:加载后,不卸载、卸载不干净重复加载。

避免内存泄露技巧 :

1. 建立明确规则
遵循“谁加载,谁卸载”原则,确保加载和卸载逻辑成对出现。不再使用的资源先销毁,最后再卸载其所属的AB包。

2. 选用正确工具与格式

  • 压缩格式:优先选用LZ4压缩,它支持按需解压,内存效率高;避免对需频繁加载的包使用LZMA(会整体解压,内存占用大)。

  • 管理方式:推荐升级使用Unity官方Addressable资源管理系统,它能通过引用计数自动管理加载与卸载,极大降低手动出错风险。

3. 借助分析工具定位问题
使用Unity Profiler观察内存曲线,配合Memory Profiler拍摄内存快照进行对比,精确定位是哪个资源未被释放及其引用源头。

  • AB 包的两种卸载方式:

  • bundle.Unload(false):只卸载AB包数据,已加载的资源保留(需自己管理)

  • bundle.Unload(true):连同AB包和从它加载的资源一起卸载(注意:可能误卸还在使用的资源)

四、新技术的冲击

  • Addressable Asset System

  • Unity官方推荐的新方案,底层还是AB包,但封装了依赖管理、异步加载、引用计数等复杂逻辑。相比直接使用AssetBundle(AB包),Addressable Asset System 最大的优势在于将资源管理的复杂性从“手动”变为“自动”,让开发者从繁重的底层细节中解放出来。

  • 💡 核心优势对比

    维度 AssetBundle (AB包) Addressable Asset System 核心优势
    依赖管理 手动:开发者需要自己分析一个资源依赖了哪些其他包,并在加载前手动编写代码,确保所有依赖包都已加载完毕。 自动:系统会分析并自动加载一个资源所需的所有依赖,你只需加载目标资源即可。 彻底告别因依赖缺失而导致的资源丢失或加载失败问题
    内存管理 手动:需自己跟踪资源生命周期,在合适时机手动调用Unload方法,稍有不慎就会造成内存泄漏或资源误卸载。 自动引用计数:系统会为每个资源记录引用次数,加载时+1,释放时-1。当计数归零时,会自动卸载其所在的AB包,极大降低了内存管理出错的概率。 提供了一套安全、自动化的内存回收机制
    打包策略 手动配置:需为每个资源手动指定AB包名,并需自行分析,避免一个共用资源被重复打进多个包里造成冗余。 基于分组:通过可视化的“分组(Group)”来组织资源,并提供了分析工具(Analyze),可以一键检测并修复潜在的资源冗余问题。 使分包工作更直观,并能有效减小最终包体大小
    远程加载与更新 手动实现:需自己写代码处理文件的网络下载、缓存和版本比对,工作量大且容易出错。 内置支持:只需在配置中指定资源的远程URL,系统就会自动处理本地加载和远程下载的切换,对业务代码完全透明。 让热更新功能的实现变得简单而标准
    开发与学习成本 :概念多,流程复杂,需要理解依赖、冗余、打包等多种概念,且后期维护成本高。 :官方封装好的高级API,学习曲线平滑。开发者可以更专注于游戏逻辑本身,而非资源加载的技术细节。 显著提升开发效率和项目可维护性

    ⚠️ 一个潜在的性能考量

    虽然Addressables优势明显,但对于资源规模极其庞大的项目,需要注意其启动时会解析一个总的资源清单文件(catalog.json),如果清单过于庞大,解析过程可能会拖慢启动速度。不过这通常只在特殊的大型项目中才需要关注。

    总的来说,Addressables通过自动化的依赖管理、安全的引用计数内存机制和一键式的资源分析工具,几乎完美地解决了原生AB包在使用中的痛点,这也是它现在成为Unity官方推荐的资源管理方案的原因

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐