AssetBundle 是 Unity 提供的一种资源打包机制,允许开发者将游戏资源(如模型、纹理、预制体等)打包成独立的文件,便于动态加载和热更新。
一、AssetBundle 基础概念
1. 什么是 AssetBundle
-  
资源压缩包,包含序列化资源文件
 -  
可以包含任意 Unity 支持的资源类型
 -  
支持按需加载和卸载
 -  
是 Unity 热更新的基础技术
 
2. AssetBundle 优势
-  
减小初始包体:将非必要资源分离
 -  
动态加载:运行时按需加载资源
 -  
热更新:不通过应用商店更新资源
 -  
资源共享:多个 AssetBundle 可以共享资源
 
二、AssetBundle 打包流程
1. 标记资源为 AssetBundle
在 Unity 编辑器中:
-  
选择要打包的资源
 -  
在 Inspector 窗口底部找到 AssetBundle 设置
 -  
创建新的 AssetBundle 名称或选择现有名称
-  
格式:
bundlename或path/bundlename(可添加子文件夹) 
 -  
 
2. 编写打包脚本
using UnityEditor;
using System.IO;public class BuildAssetBundles
{[MenuItem("Assets/Build AssetBundles")]static void BuildAllAssetBundles(){// 创建输出目录(如果不存在)string outputPath = "Assets/AssetBundles";if (!Directory.Exists(outputPath)){Directory.CreateDirectory(outputPath);}// 开始打包BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);Debug.Log("AssetBundle 打包完成!");}
} 
3. 打包选项详解
BuildAssetBundleOptions 常用选项:
| 选项 | 说明 | 
|---|---|
| None | 默认选项,使用 LZMA 压缩 | 
| UncompressedAssetBundle | 不压缩,加载快但体积大 | 
| ChunkBasedCompression | 使用 LZ4 压缩,平衡体积和性能 | 
| DisableWriteTypeTree | 不包含类型信息,减小包体但可能不兼容 | 
| DeterministicAssetBundle | 确保相同内容生成相同 hash | 
| ForceRebuildAssetBundle | 强制重新打包所有 AssetBundle | 
三、高级打包技巧
1. 依赖管理
// 获取资源依赖
string[] dependencies = AssetDatabase.GetDependencies("Assets/Prefabs/Player.prefab");// 打包时自动处理依赖
// Unity 会自动将共享资源提取到单独的 AssetBundle 
2. 变体系统
// 设置带变体的 AssetBundle 名称
// 格式:bundlename.variant
// 例如:character.hd 和 character.sd// 运行时根据设备选择加载哪个变体
AssetBundle.LoadFromFile("path/to/character.hd"); 
3. 脚本化打包
// 更精细控制的打包方式
var builds = new AssetBundleBuild[2];// 第一个 AssetBundle
builds[0].assetBundleName = "environment";
builds[0].assetNames = new[] {"Assets/Scenes/Forest.unity","Assets/Textures/Terrain.psd"
};// 第二个 AssetBundle
builds[1].assetBundleName = "characters";
builds[1].assetNames = new[] {"Assets/Prefabs/Player.prefab","Assets/Animations/Player.controller"
};BuildPipeline.BuildAssetBundles("Assets/AssetBundles", builds, BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.StandaloneWindows); 
四、AssetBundle 清单文件
打包后会生成以下重要文件:
-  
AssetBundles/[YourPlatform]: 各个 AssetBundle 文件
 -  
AssetBundles/[YourPlatform].manifest: 平台总体清单
 -  
AssetBundles/[EachBundle].manifest: 每个 AssetBundle 的清单
 
清单文件包含:
-  
资源信息
 -  
依赖信息
 -  
CRC 校验码
 -  
资源哈希值
 
五、AssetBundle 加载方式
1. 本地加载
// 同步加载
AssetBundle localAB = AssetBundle.LoadFromFile("Assets/AssetBundles/characters");
GameObject playerPrefab = localAB.LoadAsset<GameObject>("Player");// 异步加载
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync("Assets/AssetBundles/characters");
yield return request;
AssetBundle localAB = request.assetBundle; 
2. 远程加载
IEnumerator LoadFromWeb()
{string url = "http://your-server.com/characters";UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url);yield return request.SendWebRequest();if(request.result == UnityWebRequest.Result.Success){AssetBundle remoteAB = DownloadHandlerAssetBundle.GetContent(request);GameObject enemyPrefab = remoteAB.LoadAsset<GameObject>("Enemy");}
} 
3. 加载依赖
// 先加载主 AssetBundle
AssetBundle manifestAB = AssetBundle.LoadFromFile("Assets/AssetBundles/StandaloneWindows");
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");// 获取依赖
string[] dependencies = manifest.GetAllDependencies("characters");// 加载所有依赖
foreach(string dependency in dependencies)
{AssetBundle.LoadFromFile("Assets/AssetBundles/" + dependency);
}// 然后加载主资源包
AssetBundle charactersAB = AssetBundle.LoadFromFile("Assets/AssetBundles/characters"); 
六、内存管理与卸载
1. 资源卸载
// 卸载单个 AssetBundle(false=只卸载AB,true=同时卸载从中加载的资源)
 assetBundle.Unload(false);
// 卸载所有未使用的 AssetBundle 和资源
 Resources.UnloadUnusedAssets();
2. 内存管理建议
-  
及时卸载不再需要的 AssetBundle
 -  
避免重复加载相同 AssetBundle
 -  
注意资源引用关系,防止内存泄漏
 -  
使用
Profiler监控内存使用情况 
七、常见问题与解决方案
1. 资源丢失或引用断裂
解决方案:
-  
确保所有依赖资源都正确打包
 -  
使用
Addressable Assets系统替代原始 AssetBundle 
2. 打包后资源变大
解决方案:
-  
检查是否包含不必要资源
 -  
使用合适的压缩方式
 -  
启用
DisableWriteTypeTree(牺牲一些兼容性) 
3. 跨平台兼容性问题
解决方案:
-  
为每个目标平台单独打包
 -  
使用
BuildTarget参数指定正确平台 
4. 热更新版本管理
解决方案:
-  
实现版本比对系统
 -  
使用哈希值或版本号管理资源
 -  
提供回滚机制
 
八、最佳实践
-  
合理划分 AssetBundle
-  
按功能模块划分(角色、场景、UI等)
 -  
按使用频率划分(基础包、常用资源、低频资源)
 -  
按场景划分(每个场景一个包)
 
 -  
 -  
压缩策略选择
-  
初始包:LZMA(高压缩率)
 -  
热更新:LZ4(快速随机访问)
 
 -  
 -  
资源冗余处理
-  
将共享资源提取到公共包
 -  
避免资源被多个包重复包含
 
 -  
 -  
开发流程
-  
开发期使用 Editor 模式直接加载
 -  
发布前切换为 AssetBundle 加载
 -  
自动化打包流程集成 CI/CD
 
 -  
 
AssetBundle 是 Unity 资源管理的强大工具,合理使用可以显著优化游戏性能并实现热更新功能。随着 Unity 发展,也可以考虑结合 Addressables 系统来获得更现代化的资源管理体验。