Beispiel #1
0
        //
        static void BuildBundles(List <BundleGenInfo> genInfos_, bool needBuild)
        {
            AssetBundleBuild[] shareBuilds = null;

            BundleGenInfo shareGenInfo = GetShareBundle();

            if (shareGenInfo != null)
            {
                //公共打包项, 这里仅为拿到AssetBundleBuild列表
                shareBuilds = BuildBundle(shareGenInfo, null, false).ToArray();
            }

            foreach (BundleGenInfo genInfo in genInfos_)
            {
                BuildBundle(genInfo, shareBuilds, needBuild);
            }

            if (shareGenInfo != null)
            {
                //把公共项添加到总表
                genInfos_.Add(shareGenInfo);
            }


            BundleLog.MakeLog(genInfos_);   //生成日志
            AbsResExport.Export(genInfos_); //生辰资源配置
        }
Beispiel #2
0
        public static void MakeLog(List <BundleGenInfo> genInfos_)
        {
            if (!Directory.Exists(log_folder_path))
            {
                Directory.CreateDirectory(log_folder_path);   //创建文件夹
            }
            string filePath = log_folder_path + "/Log_abs " + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".txt";

            StringBuilder strBundler = new StringBuilder();

            for (int i = 0; i < genInfos_.Count; ++i)
            {
                BundleGenInfo genInfo = genInfos_[i];

                //包名
                strBundler.AppendLine("bundle_name:" + genInfo.bundleName);

                string tab = TAB;
                //依赖
                strBundler.AppendLine(tab + "bundle_depend:");
                LogAsset(genInfo.dpAssets, strBundler, tab);
                //资源列表
                LogAsset(genInfo.assets, strBundler, "");
            }

            File.WriteAllBytes(filePath, Encoding.UTF8.GetBytes(strBundler.ToString()));
            Debug.Log("导出打包日志: " + filePath);
        }
Beispiel #3
0
        public static void Collect_s(BundleGenInfo info_)
        {
            BdlCollect collect = null;

            switch (info_.packType)
            {
            case PACK_TYPE.LD_FST:
                collect = new BdlCollectLdFst();
                break;
            }

            if (collect != null)
            {
                collect.Collect(info_);
            }
        }
Beispiel #4
0
        static BundleGenInfo GetShareBundle()
        {
            AssetGroup[] assetInfos = new AssetGroup[]
            {
                GetShareAsset_Font(),
                GetShareAsset_Shader(),
            };

            BundleGenInfo genInfo = new BundleGenInfo();

            genInfo.bundleName = "share";
            genInfo.combineNum = 1;
            genInfo.assets.AddRange(assetInfos);

            return(genInfo);
        }
Beispiel #5
0
 public virtual void Collect(BundleGenInfo info_)
 {
 }
Beispiel #6
0
        /// <summary>
        /// 根据manifest重置单个GenInfo的依赖关系
        /// (主要是补全顶级文件依赖顶级文件这种情况)
        /// </summary>
        /// <param name="manifest"></param>
        /// <param name="genInfo_"></param>
        public static void ResetDependsByManifest(AssetBundleManifest manifest, BundleGenInfo genInfo_)
        {
            string[] bundlePaths = manifest.GetAllAssetBundles();

            foreach (string bundlePath in bundlePaths)
            {
                string bundleName = GetBdlNameByExportPath(bundlePath);

                foreach (AssetGroup assetInfo in genInfo_.assets)
                {
                    if (assetInfo.name.ToLower() != bundleName)
                    {
                        continue;
                    }

                    List <AssetGroup> newDpAssets = new List <AssetGroup>();

                    string[] dpPaths = manifest.GetDirectDependencies(bundlePath);  //获取实际用到的依赖路径
                    foreach (var dpPath in dpPaths)
                    {
                        var  dpBundleName = GetBdlNameByExportPath(dpPath);
                        bool areadyIn     = false;
                        foreach (AssetGroup a in newDpAssets)
                        {
                            if (a.name.ToLower() == dpBundleName)
                            {
                                areadyIn = true;
                                break;
                            }
                        }
                        if (!areadyIn)
                        {
                            bool found = false;
                            foreach (AssetGroup assetInfo2 in genInfo_.assets)
                            {
                                if (assetInfo2.name.ToLower() == dpBundleName)
                                {
                                    found = true;
                                    newDpAssets.Add(assetInfo2);
                                }
                                foreach (AssetGroup dpAsset in assetInfo2.dpAssets)
                                {
                                    if (dpAsset.name.ToLower() == dpBundleName)
                                    {
                                        newDpAssets.Add(dpAsset);
                                        found = true;
                                    }
                                }
                                if (found)
                                {
                                    break;
                                }
                            }
                        }
                    }

                    List <AssetGroup> oldDpAssets = assetInfo.dpAssets;
                    assetInfo.dpAssets = newDpAssets;

                    //打印修正信息
                    //增加
                    foreach (AssetGroup a1 in newDpAssets)
                    {
                        if (!oldDpAssets.Contains(a1))
                        {
                            Log.Debug(string.Format("依赖修正: {0} {1} 增加: {2}", genInfo_.bundleName, assetInfo.name, a1.name));
                        }
                    }
                    //删除
                    foreach (AssetGroup a1 in oldDpAssets)
                    {
                        if (!newDpAssets.Contains(a1))
                        {
                            Log.Debug(string.Format("依赖修正: {0} {1} 删除: {2}", genInfo_.bundleName, assetInfo.name, a1.name));
                        }
                    }
                }
            }
        }
Beispiel #7
0
        public override void Collect(BundleGenInfo genInfo_)
        {
            string bundleName = genInfo_.bundleName;

            HashSet <string> topFileHash = new HashSet <string>();

            foreach (PathInfo pathInfo in genInfo_.pathInfos)
            {
                //顶级文件列表
                List <string> topFiles = new List <string>();
                //递归收集所有文件
                BundleUtility.CollectPathWithSuffix(pathInfo.path, pathInfo.suffixs, topFiles, pathInfo.exclude);
                //按名称排序
                topFiles.Sort();

                int bundleId = 0;
                int curIdx   = 0;
                while (curIdx < topFiles.Count)
                {
                    string     name  = bundleName + "_" + bundleId; //gui_0
                    AssetGroup asset = new AssetGroup();
                    asset.name      = name;
                    asset.isPatch   = false;
                    asset.isTopFile = true;

                    //合并
                    for (int i = 0; i < pathInfo.combineNum && curIdx < topFiles.Count; ++i, ++curIdx)
                    {
                        asset.files.Add(topFiles[curIdx]);
                        topFileHash.Add(topFiles[curIdx]);

                        BundleBuilder.AddAsset(topFiles[curIdx], asset);    //关联文件路径与BundleAsset
                    }

                    bundleId++;
                    genInfo_.assets.Add(asset);
                }
            }


            //收集依赖
            var asset2dpPathSet = new Dictionary <AssetGroup, HashSet <string> >();    //A的dpPathSet与B的此时可能会有重复依赖项

            foreach (AssetGroup asset in genInfo_.assets)
            {
                var __dpPathSet = new HashSet <string>();
                asset2dpPathSet[asset] = __dpPathSet;

                foreach (string path in asset.files)
                {
                    BundleUtility.CollectDepends(path, __dpPathSet);
                }

                //排除顶级依赖
                List <string> excludes = new List <string>();
                foreach (string path in __dpPathSet)
                {
                    if (topFileHash.Contains(path))    //这个依赖是顶级文件
                    {
                        excludes.Add(path);
                        //如果有依赖项是顶级文件,便直接添加到asset的depends中, 这些文件不视为外部依赖
                        AssetGroup topAsset = BundleBuilder.CreateAsset(path);
                        if (!asset.dpAssets.Contains(topAsset))
                        {
                            asset.dpAssets.Add(topAsset);
                        }
                    }
                }

                foreach (string path in excludes)   //从pathHash移除掉
                {
                    __dpPathSet.Remove(path);
                }
            }

            // 统计一个dependPath被包含到多少个Asset里
            var dpPath2assetSet = new Dictionary <string, HashSet <AssetGroup> >();

            foreach (var kvp in asset2dpPathSet)
            {
                AssetGroup       asset       = kvp.Key;
                HashSet <string> __dpPathSet = kvp.Value;
                foreach (string dpPath in __dpPathSet)
                {
                    HashSet <AssetGroup> assetHash;
                    if (!dpPath2assetSet.TryGetValue(dpPath, out assetHash))
                    {
                        assetHash = new HashSet <AssetGroup>();
                        dpPath2assetSet[dpPath] = assetHash;
                    }
                    assetHash.Add(asset);         //dpPath -> {AssetGroup, ...}
                }
            }

            List <string> toDelPaths = new List <string>();

            //只被一个文件依赖, 和此文件一起打包
            foreach (var kvp in dpPath2assetSet)
            {
                string dpPath = kvp.Key;
                HashSet <AssetGroup> assetHash = kvp.Value;
                if (assetHash.Count <= 1) //排查出只有一个引用的依赖
                {
                    AssetGroup       parentAsset = assetHash.First();
                    HashSet <string> __dpPathSet = asset2dpPathSet[parentAsset];
                    __dpPathSet.Remove(dpPath);      //从引用者的dpPathHash里面移除, 从而不属于公共依赖

                    toDelPaths.Add(dpPath);
                }
            }

            //dpPath2assetSet里只保留引用数>1的路径
            foreach (string path in toDelPaths)
            {
                dpPath2assetSet.Remove(path);
            }

            //对所有依赖进行排序
            List <string> mainDpPaths = new List <string>();

            mainDpPaths.AddRange(dpPath2assetSet.Keys);
            mainDpPaths.Sort((r, l) =>
            {
                if (dpPath2assetSet[r].Count != dpPath2assetSet[l].Count)
                {
                    //优先按依赖数量排序
                    return(dpPath2assetSet[l].Count - dpPath2assetSet[r].Count);
                }
                return(l.CompareTo(r));
            });

            //依赖总表
            HashSet <string> mainDpPathSet = new HashSet <string>();

            foreach (string path in mainDpPaths)
            {
                mainDpPathSet.Add(path);
            }


            HashSet <string> tmpDpPathSet = new HashSet <string>();
            List <string>    tmpDpPaths   = new List <string>();

            int index = 0;

            while (index < mainDpPaths.Count)
            {
                if (!mainDpPathSet.Contains(mainDpPaths[index]))
                {
                    //已经处理过
                    index++;
                    continue;
                }

                //50个依赖文件->dpPaths
                int           combineCnt = 50; //一个包的依赖文件个数
                List <string> dpFiles    = new List <string>();
                while (dpFiles.Count < combineCnt && index < mainDpPaths.Count)
                {
                    string path = mainDpPaths[index];
                    if (mainDpPathSet.Contains(path))
                    {
                        //还没处理过
                        mainDpPathSet.Remove(path);
                        dpFiles.Add(path);
                    }
                    index++;
                }

                //此时dpFiles有50个依赖文件

                bool hasMore = true;
                while (hasMore)
                {
                    hasMore = false;

                    tmpDpPaths.Clear();
                    tmpDpPaths.AddRange(dpFiles);

                    tmpDpPathSet.Clear();
                    BundleUtility.CollectDepends(tmpDpPaths.ToArray(), tmpDpPathSet); //收集这个依赖列表的所有依赖项

                    foreach (string path in tmpDpPathSet)
                    {
                        if (mainDpPathSet.Contains(path))
                        {
                            //次依赖在总表里,收集到本次列表里
                            mainDpPathSet.Remove(path);
                            dpFiles.Add(path);

                            hasMore = true;
                        }
                    }


                    //查找剩下全部依赖
                    tmpDpPaths.Clear();
                    tmpDpPaths.AddRange(mainDpPathSet);
                    foreach (string path in tmpDpPaths)
                    {
                        if (mainDpPathSet.Contains(path))
                        {
                            tmpDpPathSet.Clear();
                            BundleUtility.CollectDepends(tmpDpPaths.ToArray(), tmpDpPathSet); //收集剩下的全部依赖的所有依赖项

                            bool packed = false;
                            foreach (string dpPath in tmpDpPathSet)
                            {
                                if (dpFiles.Contains(dpPath))
                                {
                                    //如果这些依赖在这次的收集列表里, 也收集进来
                                    dpFiles.Add(path);
                                    mainDpPathSet.Remove(path);

                                    hasMore = true;
                                    packed  = true;
                                    break;
                                }
                            }

                            if (packed)
                            {
                                foreach (var dpPath in tmpDpPathSet)
                                {
                                    if (mainDpPathSet.Contains(dpPath))
                                    {
                                        mainDpPathSet.Remove(dpPath);
                                        //所有依赖里面在总表的都添加到这次的收集
                                        dpFiles.Add(dpPath);
                                    }
                                }
                            }
                        }
                    }
                }

                if (dpFiles.Count > 0)
                {
                }
            }
        }
Beispiel #8
0
        public override void Collect(BundleGenInfo genInfo_)
        {
            string bundleName = genInfo_.bundleName;

            //顶级文件列表
            List <string> topFiles = new List <string>();

            foreach (var pathInfo in genInfo_.pathInfos)
            {
                BundleUtility.CollectPathWithSuffix(pathInfo.path, pathInfo.suffixs, topFiles, pathInfo.exclude);    //递归收集所有文件
            }
            //按名称排序
            topFiles.Sort();


            foreach (string path in topFiles)
            {
                AssetGroup assetInfo = BundleBuilder.CreateAsset(path);
                assetInfo.isTopFile = true;   //是顶级文件
                genInfo_.assets.Add(assetInfo);
            }

            //收集依赖
            var asset2dpPathSet = new Dictionary <AssetGroup, HashSet <string> >();

            foreach (AssetGroup asset in genInfo_.assets)
            {
                HashSet <string> dpPathSet = new HashSet <string>();
                asset2dpPathSet[asset] = dpPathSet;

                foreach (string filePath in asset.files)     //到这里的files应该只有一个文件,之后会添加
                {
                    BundleUtility.CollectDepends(filePath, dpPathSet);
                }

                //排除顶级依赖
                List <string> excludes = new List <string>();
                foreach (string path in dpPathSet)
                {
                    if (topFiles.Contains(path))    //这个依赖是顶级文件
                    {
                        excludes.Add(path);
                        //如果有依赖项是顶级文件,便直接添加到asset的depends中, 这些文件不视为外部依赖
                        asset.dpAssets.Add(BundleBuilder.CreateAsset(path));
                    }
                }

                foreach (string path in excludes)   //从pathHash移除掉
                {
                    dpPathSet.Remove(path);
                }
            }

            // 统计一个dependPath被包含到多少个Asset里
            var dpPath2assetSet = new Dictionary <string, HashSet <AssetGroup> >();

            foreach (var kvp in asset2dpPathSet)
            {
                AssetGroup       asset     = kvp.Key;
                HashSet <string> dpPathSet = kvp.Value;
                foreach (string dpPath in dpPathSet)
                {
                    HashSet <AssetGroup> assetHash;
                    if (!dpPath2assetSet.TryGetValue(dpPath, out assetHash))
                    {
                        assetHash = new HashSet <AssetGroup>();
                        dpPath2assetSet[dpPath] = assetHash;
                    }
                    assetHash.Add(asset);         //dpPath -> {assetInfo, ...}
                }
            }

            List <string> toDelPath = new List <string>();

            // 只被一个文件依赖的 就和这个文件打包在一起,不再区分
            foreach (var kvp in dpPath2assetSet)
            {
                string dpPath = kvp.Key;
                HashSet <AssetGroup> assetHash = kvp.Value;
                if (assetHash.Count <= 1) //排查出只有一个引用的依赖
                {
                    AssetGroup       parentAsset = assetHash.First();
                    HashSet <string> dpPathSet   = asset2dpPathSet[parentAsset];
                    dpPathSet.Remove(dpPath);      //从引用者的dpPathHash里面移除, 从而不属于公共依赖

                    toDelPath.Add(dpPath);
                }
            }

            //dpPath2assetSet里只保留引用数>1的路径
            foreach (string path in toDelPath)
            {
                dpPath2assetSet.Remove(path);
            }



            //建立无向图(所有依赖的连通图) { {A(a,b,c), B(a,d,e) } -> { a(b,c,d,e), b(c,a), c(a,b), d(a,e), e(a,d) }
            var path2node = new Dictionary <string, GraphNode>();

            foreach (var kvp in asset2dpPathSet)
            {
                AssetGroup       asset     = kvp.Key;
                HashSet <string> dpPathSet = kvp.Value;   //被同一个资源引用的依赖列表
                foreach (string dpPath in dpPathSet)
                {
                    GraphNode dpNode;
                    if (!path2node.TryGetValue(dpPath, out dpNode))  //为所有依赖创建节点
                    {
                        dpNode            = new GraphNode();
                        dpNode.path       = dpPath;
                        path2node[dpPath] = dpNode;
                    }

                    foreach (string dpPath2 in dpPathSet)
                    {
                        if (dpPath2 == dpPath)
                        {
                            continue;
                        }

                        GraphNode dpNode2;
                        if (path2node.TryGetValue(dpPath2, out dpNode2))
                        {
                            //互相把自己添加到对方的edges
                            dpNode2.edges.Add(dpNode);
                            dpNode.edges.Add(dpNode2);
                        }
                    }
                }
            }

            //创建节点块(把所有连通的依赖独立出来一块) { (a,b,c,d,e), (...) }
            var nodeSets = new List <HashSet <GraphNode> >();

            foreach (var kvp in path2node)
            {
                GraphNode node = kvp.Value;
                if (!node.visited)
                {
                    HashSet <GraphNode> nodeSet = new HashSet <GraphNode>();
                    VisitNode(node, nodeSet);
                    nodeSets.Add(nodeSet);
                }
            }


            int idx = 0;

            foreach (var nodeSet in nodeSets)
            {
                AssetGroup dpAsset   = new AssetGroup();
                string     dpBdlName = Path.Combine("depends", string.Format("{0}_{1}", bundleName, idx)); //depends/gui_0
                dpAsset.name      = FileUtility.FomatPath(dpBdlName);
                dpAsset.isTopFile = false;

                foreach (GraphNode node in nodeSet)
                {
                    dpAsset.files.Add(node.path);
                }


                //如果顶级文件的依赖项里有依赖这个块的其中一个文件,便把这个块的包作为顶级文件的依赖项
                foreach (var kvp in asset2dpPathSet)
                {
                    AssetGroup       asset     = kvp.Key;
                    HashSet <string> dpPathSet = kvp.Value;

                    foreach (string dpPath in dpAsset.files)
                    {
                        if (dpPathSet.Contains(dpPath))
                        {
                            asset.dpAssets.Add(dpAsset);
                            break;
                        }
                    }
                }

                genInfo_.dpAssets.Add(dpAsset);      //添加到总依赖列表
                ++idx;
            }
        }
Beispiel #9
0
        static void ReadExcelConfig(FileStream stream, string sheetName, List <BundleGenInfo> genInfos)
        {
            Dictionary <string, BundleGenInfo> name2genInfo = new Dictionary <string, BundleGenInfo>();

            /// 读取excel配置
            IWorkbook workbook = new HSSFWorkbook(stream);
            ISheet    sheet    = workbook.GetSheet(sheetName);

            int rowCount = sheet.LastRowNum;

            for (int i = 1; i <= rowCount; ++i) //数据从第二行开始
            {
                IRow row = sheet.GetRow(i);     //获取行数据
                if (row == null)
                {
                    break;
                }

                ICell pathCell = row.GetCell((int)ExcelRID.Path);
                if (pathCell == null || string.IsNullOrEmpty(pathCell.StringCellValue))
                {
                    break;
                }

                //打包路径
                string path = pathCell.StringCellValue;

                ICell bundleNameCell = row.GetCell((int)ExcelRID.BundleName);
                if (bundleNameCell == null || string.IsNullOrEmpty(bundleNameCell.StringCellValue))
                {
                    break;
                }

                //包名
                string bundleName = bundleNameCell.StringCellValue;

                BundleGenInfo genInfo;
                if (name2genInfo.ContainsKey(bundleName))
                {
                    genInfo = name2genInfo[bundleName];     //同一包名的项收集在一个genInfo里
                }
                else
                {
                    genInfo = new BundleGenInfo();
                    //包名
                    genInfo.bundleName = bundleName;
                    //打包方式
                    genInfo.packType = row.GetCell((int)ExcelRID.PackType).StringCellValue; //因此同一个包名的打包方式应该一致
                    //分包数
                    genInfo.combineNum = 1;

                    //作为场景打包
                    //var isSceneCell = row.GetCell((int)ExcelRID.AsScene);
                    //if (isSceneCell != null && !string.IsNullOrEmpty(isSceneCell.StringCellValue))
                    //{
                    //    genInfo.isScene = true;
                    //}

                    name2genInfo[bundleName] = genInfo;
                }

                BundleGenInfo.PathInfo pathInfo = new BundleGenInfo.PathInfo();
                genInfo.pathInfos.Add(pathInfo);

                pathInfo.path = path.Trim();

                //ID(并没有作用)
                string idStr = row.GetCell((int)ExcelRID.ID).StringCellValue;
                if (!string.IsNullOrEmpty(idStr))
                {
                    pathInfo.id = idStr.Trim();   //去掉边缘空格
                }

                var combineNumCell = row.GetCell((int)ExcelRID.CombineNum);
                if (combineNumCell != null && !string.IsNullOrEmpty(combineNumCell.StringCellValue))
                {
                    pathInfo.combineNum = int.Parse(combineNumCell.StringCellValue);
                    pathInfo.combineNum = Math.Max(pathInfo.combineNum, 1);

                    genInfo.combineNum = pathInfo.combineNum;
                }


                //打包的后缀名
                string suffixStr = row.GetCell((int)ExcelRID.Suffixs).StringCellValue;
                if (!string.IsNullOrEmpty(suffixStr))
                {
                    pathInfo.suffixs = suffixStr.Split(',');
                    for (int j = 0; j < pathInfo.suffixs.Length; ++j)
                    {
                        pathInfo.suffixs[j] = pathInfo.suffixs[j].Trim();   //去掉边缘空格
                    }
                }

                //排除的文件/目录名称
                string exclueStr = row.GetCell((int)ExcelRID.Exclude).StringCellValue;
                if (!string.IsNullOrEmpty(exclueStr))
                {
                    pathInfo.exclude = exclueStr.Split(',');
                    for (int j = 0; j < pathInfo.exclude.Length; ++j)
                    {
                        pathInfo.exclude[j] = pathInfo.exclude[j].Trim();   //去掉边缘空格
                    }
                }

                if (!genInfos.Contains(genInfo))    //保证只有一个
                {
                    genInfos.Add(genInfo);
                }
            }


            workbook.Close();
        }
Beispiel #10
0
        /// <summary>
        /// 根据单个生成信息打包
        /// </summary>
        /// <param name="genInfo"></param>
        /// <param name="shareBuilds_">公共打包项</param>
        /// <param name="needBuild">是否需要build</param>
        /// <returns></returns>
        static List <AssetBundleBuild> BuildBundle(BundleGenInfo genInfo, AssetBundleBuild[] shareBuilds_, bool needBuild)
        {
            //先排个序
            genInfo.assets.Sort((l, r) =>
            {
                return(l.name.CompareTo(r.name));
            });

            List <AssetBundleBuild> bundleBuilds = new List <AssetBundleBuild>();

            if (shareBuilds_ != null) //公共打包项
            {
                bundleBuilds.AddRange(shareBuilds_);
            }

            //建立依赖的BundleBuild
            foreach (var dpAsset in genInfo.dpAssets)
            {
                dpAsset.name = BundleUtility.GetBundleOutputName(dpAsset.name);     //重新定义包名

                AssetBundleBuild build = new AssetBundleBuild();
                build.assetBundleName = dpAsset.name;
                build.assetNames      = dpAsset.files.ToArray(); //每个依赖列表打成一个包
                bundleBuilds.Add(build);
            }

            int bdlIdx     = 0;
            int combineNum = genInfo.combineNum;

            List <AssetGroup> newAssets  = new List <AssetGroup>();
            List <AssetGroup> assetInfos = genInfo.assets;

            while (bdlIdx < assetInfos.Count)
            {
                AssetGroup assetInfo = assetInfos[bdlIdx];

                AssetBundleBuild build = new AssetBundleBuild();
                var dpAssetSet         = new HashSet <AssetGroup>();

                //按分包数收集包含的所有files
                List <string> files = new List <string>();
                for (int i = 0; i < combineNum && bdlIdx < assetInfos.Count; ++i)
                {
                    files.AddRange(assetInfos[bdlIdx].files);    //添加文件路径

                    List <AssetGroup> dpAssets = assetInfos[bdlIdx].dpAssets;
                    foreach (AssetGroup dpAsset in dpAssets)
                    {
                        dpAssetSet.Add(dpAsset);
                    }
                    ++bdlIdx;
                }


                //重定义名称
                if (combineNum > 1 && !string.IsNullOrEmpty(genInfo.bundleName)) //需要分包
                {
                    var name    = assetInfo.name.Replace("\\", "/");             //只取第一个asset的话,感觉会有问题, 如果里面掺杂了其他remainName,会单独打出一个包了
                    var lastIdx = name.LastIndexOf("/");

                    var remainPath = name.Substring(0, lastIdx);                                     //Resources\GUI\cn\Prefab
                    var remainName = Path.GetFileName(remainPath);                                   //Prefab  其实就是文件夹名称
                    remainPath = remainPath.Substring(0, remainPath.Length - remainName.Length - 1); //Resources\GUI\cn
                    int idxSuffix = 0;
                    if (!genInfo.curCombineIdx.ContainsKey(remainName))                              //这里有点繁琐,可以优化一下
                    {
                        genInfo.curCombineIdx[remainName] = 0;
                    }
                    idxSuffix = genInfo.curCombineIdx[remainName];
                    genInfo.curCombineIdx[remainName] = idxSuffix + 1;

                    assetInfo.name        = BundleUtility.GetBundleOutputName(remainPath + "/" + remainName + "_" + idxSuffix.ToString());
                    build.assetBundleName = assetInfo.name;
                }
                else
                {
                    assetInfo.name        = BundleUtility.GetBundleOutputName(assetInfo.name); //格式化成输出用的名称
                    build.assetBundleName = assetInfo.name;
                }

                assetInfo.files = files;        //覆盖为新的文件列表
                newAssets.Add(assetInfo);       //添加到新的asset列表

                //覆盖为新的依赖列表
                List <AssetGroup> newDpAssets = new List <AssetGroup>();
                foreach (AssetGroup dpAsset in dpAssetSet)
                {
                    newDpAssets.Add(dpAsset);
                }
                assetInfo.dpAssets = newDpAssets;

                build.assetNames = files.ToArray();
                bundleBuilds.Add(build);
            }

            //覆盖为新的Asset列表
            genInfo.assets = newAssets;

            if (needBuild)
            {
                //执行打包
                AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(PATH_BUNDLE_ROOT, bundleBuilds.ToArray(), CurrentBuildAssetOpts, m_buildTarget);
                //根据manifest矫正一下依赖情况
                BundleUtility.ResetDependsByManifest(manifest, genInfo);
            }

            return(bundleBuilds);
        }