为什么要自己写打包细分包策略我们知道Unity内置的打包方案是在右下角指定包名。我们看到商业项目都在使用细分包策略一个包装一个预制体包括它的模型、材质、贴图、脚本。或者装一个图标、大图、声音、动画。一个游戏有上百个甚至上千个包。这样能做到最精准的热更更新资源时下载最少的数据。那么如果用Unity内置打包就选一个预制体选择它的依赖全部打上包名。只是这个过程要重复几十上百次。我们知道预制体路径都是要填在配表的如果采用细分包包名也要填到配表。那么在Unity内置工具把这些包名手填一遍就是大量重复劳动。那么我们自然想到让编辑器工具读取配表去打包。这里又分为两种策略可以先根据配表设置包名也可以直接打包。我们发现官方的工具在浏览包内容、依赖时是很好用的。所以采取工具设置包名-browser检查包内容和依赖-打包的策略。细分包用内置设置包名后看起来是这样的。很明显不可能手填包名。依赖处理、防止重复包含使用string[] deps AssetDatabase.GetDependencies(path, true);获得依赖。我们发现获取的依赖包括资源本身、脚本、着色器包括内置着色器。脚本、内置着色器是无法打包的。需要根据类型过滤后再设置包名。可以用白名单或者黑名单过滤。打印一下所有依赖项的类型string[] deps AssetDatabase.GetDependencies(path, true); foreach (string dep in deps) { importerAssetImporter.GetAtPath(dep); UnityEngine.Object depObj AssetDatabase.LoadAssetAtPath UnityEngine.Object(dep); MyTools.Print(类型是depObj.GetType(), Color.green);当依赖的包名已经不为空且和主资源包名不同时需要某种处理。如果想引起人的注意直接弹窗那么弹窗应该有几个选项保持原名和设置为目标名字。但其实我们想要的是要么打成公共包要么这些都打成一个包。我们决定一个资源已经有包名时放弃修改包名打印报错。public static T CheckResT(string path, string ABName) where T : UnityEngine.Object { ABName ABName.ToLower();//AB包名全是小写 T t AssetDatabase.LoadAssetAtPathT(path); if (t ! null) { MyTools.Print(${path}存在。, Color.cyan); var importer AssetImporter.GetAtPath(path); if (!string.IsNullOrEmpty(ABName)) { if (importer.assetBundleName ! ABName) { importer.assetBundleName ABName; MyTools.Print($设置了{path}的AB包名为{ABName}); } string[] deps AssetDatabase.GetDependencies(path, true); foreach (string dep in deps) { importerAssetImporter.GetAtPath(dep); UnityEngine.Object depObj AssetDatabase.LoadAssetAtPath UnityEngine.Object(dep); MyTools.Print(类型是depObj.GetType(), Color.green); if (depObj is GameObject||depObj is Texture2D|| depObj is AudioClip) { if (!string.IsNullOrEmpty(importer.assetBundleName) importer.assetBundleName ! ABName) { //处理重复包含 Debug.LogError(${dep}希望设置包名{ABName}但已经有包名{importer.assetBundleName}请手动处理); } else { importer.assetBundleName ABName; } } } } } else { Debug.LogError($在{path}找不到{typeof(T)}); } return t; }同一个资源被指定2次包名在配表里遇到了多个物品用一个图标。在批量设置包名时我是直接给Id加_Icon很难注意到多个道具共用一个图标。程序会检测出