Unity:如何将每个AssetBundle构建到独立命名目录中
实现Unity编辑器一键按AssetBundle名称分文件夹构建的方案
嘿,刚好我之前也折腾过类似的需求,结合你提到的AssetBundleBuild和BuildPipeline,咱们可以轻松实现按AssetBundle名称分文件夹输出的功能,下面是具体的实现步骤和代码:
核心思路
咱们的目标是让每个AssetBundle的产物都放到以它自己名字命名的独立文件夹里,核心就是为每个AssetBundle单独配置构建路径:
- 先收集所有已标记的AssetBundle名称(排除空名称和重复项)
- 对每个AssetBundle,创建对应的
AssetBundleBuild配置,指定它的输出路径为「根输出目录/AssetBundle名称/」 - 最后调用
BuildPipeline.BuildAssetBundles批量构建
完整编辑器代码实现
直接上可运行的编辑器代码,你可以把它放到Editor文件夹下:
using UnityEditor; using UnityEngine; using System.Collections.Generic; using System.IO; public class AssetBundleBuilder : EditorWindow { private string outputRootPath = "Assets/AssetBundles"; [MenuItem("Tools/构建所有AssetBundle到对应文件夹")] public static void OpenBuilderWindow() { GetWindow<AssetBundleBuilder>("AB分文件夹构建"); } private void OnGUI() { GUILayout.Label("AssetBundle构建配置", EditorStyles.boldLabel); // 输出根目录设置 outputRootPath = EditorGUILayout.TextField("输出根路径", outputRootPath); if (GUILayout.Button("选择输出目录")) { string selectedPath = EditorUtility.OpenFolderPanel("选择AssetBundle输出根目录", outputRootPath, ""); if (!string.IsNullOrEmpty(selectedPath)) { outputRootPath = selectedPath; } } GUILayout.Space(20); // 构建按钮 if (GUILayout.Button("开始构建所有AssetBundle", GUILayout.Height(40))) { BuildAllAssetBundlesToFolders(); } } private void BuildAllAssetBundlesToFolders() { if (string.IsNullOrEmpty(outputRootPath)) { EditorUtility.DisplayDialog("错误", "请设置有效的输出根路径!", "确定"); return; } // 收集所有非空的AssetBundle名称,去重 HashSet<string> abNames = new HashSet<string>(); string[] allAssetPaths = AssetDatabase.GetAllAssetPaths(); foreach (string path in allAssetPaths) { string abName = AssetImporter.GetAtPath(path).assetBundleName; if (!string.IsNullOrEmpty(abName) && !abNames.Contains(abName)) { abNames.Add(abName); } } if (abNames.Count == 0) { EditorUtility.DisplayDialog("提示", "没有找到已标记的AssetBundle!", "确定"); return; } // 为每个AssetBundle创建单独的构建配置 List<AssetBundleBuild> buildList = new List<AssetBundleBuild>(); foreach (string abName in abNames) { // 收集当前AssetBundle下的所有资源路径 List<string> assetPaths = new List<string>(); foreach (string path in allAssetPaths) { if (AssetImporter.GetAtPath(path).assetBundleName == abName) { assetPaths.Add(path); } } // 创建构建配置,指定输出路径为 根目录/AB名称/ AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = Path.Combine(abName, abName); // 这里让AB包放在对应文件夹下 // 如果有变体的话,可以在这里设置build.assetBundleVariant build.assetNames = assetPaths.ToArray(); buildList.Add(build); } // 创建输出目录(确保存在) if (!Directory.Exists(outputRootPath)) { Directory.CreateDirectory(outputRootPath); } // 执行构建 BuildReport report = BuildPipeline.BuildAssetBundles( outputRootPath, buildList.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.DeterministicAssetBundle, EditorUserBuildSettings.activeBuildTarget ); // 构建结果提示 if (report.summary.result == BuildResult.Succeeded) { EditorUtility.DisplayDialog("成功", $"所有AssetBundle构建完成!输出路径:{outputRootPath}", "确定"); AssetDatabase.Refresh(); } else { EditorUtility.DisplayDialog("失败", $"构建出错,请查看控制台日志", "确定"); } } }
关键细节说明
- 去重处理:用
HashSet收集AssetBundle名称,避免重复构建同一个AB包 - 路径配置:
build.assetBundleName = Path.Combine(abName, abName)这一行是核心,它会让Unity把当前AB包输出到「根目录/AB名称/」文件夹下 - 变体支持:如果你的项目用了AssetBundle变体(比如不同分辨率的资源),可以在创建
AssetBundleBuild时设置build.assetBundleVariant,变体文件也会自动放到对应AB名称的文件夹里 - 构建选项:这里用了
ChunkBasedCompression(分块压缩,支持增量更新)和DeterministicAssetBundle(生成稳定的哈希值),你可以根据项目需求调整
使用方法
- 把代码放到Unity项目的
Editor文件夹下(没有的话新建一个) - 打开Unity编辑器,顶部菜单点击
Tools -> 构建所有AssetBundle到对应文件夹 - 在弹出的窗口里设置输出根路径,或者点击「选择输出目录」指定路径
- 点击「开始构建所有AssetBundle」,等待完成即可
这样构建完成后,你就能在输出根目录下看到每个AssetBundle对应的独立文件夹,里面就是该AB包的所有产物啦!
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

