Unity预制体导出为.unity3d格式Asset Bundle后加载报错问题
Unity AssetBundle打包(含子预制体)错误修正
原代码存在的问题
- 打开保存面板后未使用用户选择的路径,硬编码输出路径导致实际打包位置与预期不符
- 未校验选中对象是否为Project窗口中的预制体资产,若选中场景中的实例会导致依赖获取失败
- 依赖处理逻辑冗余,脚本文件标记为null但未彻底过滤(虽不影响最终列表,但代码不够严谨)
- 未处理子预制体已分配其他AssetBundle的情况,这会导致Unity跳过该依赖,加载时缺失资源
修正后的代码
using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.IO; #if UNITY_EDITOR public class AssetBundleBuilder : EditorWindow { [MenuItem("Assets/Asset Bundle Builder")] static void BuildAssetBundle() { // 校验选中对象是否为预制体资产(必须在Project窗口选中) GameObject selectedPrefab = Selection.activeObject as GameObject; if (selectedPrefab == null || PrefabUtility.GetPrefabAssetType(selectedPrefab) == PrefabAssetType.NotAPrefab) { Debug.LogError("请在Project窗口中选择一个预制体进行打包!"); return; } string bundleName = selectedPrefab.name; List<string> assetPaths = new List<string>(); // 获取用户选择的保存路径 string savePath = EditorUtility.OpenFolderPanel("选择AssetBundle保存路径", "", ""); if (string.IsNullOrEmpty(savePath)) { Debug.LogError("未选择保存路径,打包终止"); return; } // 获取预制体的所有依赖(包含间接依赖,仅资产文件) string prefabPath = AssetDatabase.GetAssetPath(selectedPrefab); string[] dependencies = AssetDatabase.GetDependencies(prefabPath, false); // 过滤脚本文件,收集唯一资产路径 foreach (string depPath in dependencies) { if (!depPath.EndsWith(".cs") && !depPath.EndsWith(".js") && !depPath.EndsWith(".boo")) { if (!assetPaths.Contains(depPath)) { assetPaths.Add(depPath); } } } // 构建打包映射 AssetBundleBuild[] buildMap = new AssetBundleBuild[1]; buildMap[0].assetBundleName = $"{bundleName}.unity3d"; buildMap[0].assetNames = assetPaths.ToArray(); // 打包选项(可根据需求调整,比如压缩选项) BuildAssetBundleOptions buildOptions = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.UncompressedAssetBundle; // 执行打包,使用用户选择的路径 BuildPipeline.BuildAssetBundles(savePath, buildMap, buildOptions, EditorUserBuildSettings.activeBuildTarget); // 刷新资源数据库 AssetDatabase.Refresh(); Debug.Log($"AssetBundle打包完成!路径:{savePath}/{bundleName}.unity3d"); } } #endif
额外注意事项
- 确保所有子预制体未被分配到其他AssetBundle分组,否则Unity会将其视为外部依赖,不会打包进当前Bundle
- 加载时需确保Bundle加载路径正确,使用
AssetBundle.LoadFromFile或对应的异步加载方法 - 若需要压缩Bundle,可移除
UncompressedAssetBundle选项,改用BuildAssetBundleOptions.ChunkBasedCompression(LZ4)或BuildAssetBundleOptions.None(LZMA)
内容的提问来源于stack exchange,提问作者Amine
相关产品推荐
相关产品推荐

