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 系統來獲得更現代化的資源管理體驗。