Ejemplo n.º 1
0
        /// <summary>
        /// 分析资源
        /// </summary>
        /// <param name="paths"></param>
        /// <param name="target"></param>
        /// <param name="outpath"></param>
        private static void AnalyzeResource(string[] paths, BuildTarget target, string outpath)
        {
            additionBuildPackageCache = new List <string>();
            CurManifestConfig         = new ManifestConfig();
            //以下三个建议使用内部函数,不要直接调用unity原生接口获取,
            allfileHashMap  = new Dictionary <string, string>();         //file hash获取缓存
            assetImpoterMap = new Dictionary <string, AssetImporter>();  //Assetimport获取缓存
            DependenciesMap = new Dictionary <string, List <string> >(); //依赖获取缓存

            //加载配置
            ManifestConfig lastManifestConfig = null;

            if (File.Exists(configPath))
            {
                lastManifestConfig = new ManifestConfig(File.ReadAllText(configPath));
            }
            else
            {
                lastManifestConfig = new ManifestConfig();
            }
            //

            /***************************************开始分析资源****************************************/
            //1.收集图集信息
            EditorUtility.DisplayProgressBar("分析资源", "收集SpriteAtlas", 0);
            GetSpriteAtlasInfo();
            //2.收集单ab多资源信息
            GetBuildAbConfig();
            //3.开始分析资源
            bool          isAdditionBuild = allfileHashMap.Count > 0; //是否为增量打包
            List <string> changeList      = new List <string>();

            for (int index = 0; index < paths.Length; index++)
            {
                var mainAssetFullPath = paths[index].Replace("\\", "/");
                EditorUtility.DisplayProgressBar("分析资源",
                                                 string.Format("分析:{0} {1}/{2}", Path.GetFileName(mainAssetFullPath), index + 1, paths.Length),
                                                 (index + 1f) / paths.Length);
                //获取被依赖的路径
                var mainAssetPath = "Assets" + mainAssetFullPath.Replace(Application.dataPath, "");
                var subAssetsPath = GetDependencies(mainAssetPath).ToList();


                List <string> subAssetHashList = new List <string>();
                //处理依赖资源打包
                for (int i = 0; i < subAssetsPath.Count; i++)
                {
                    var    subAsset     = subAssetsPath[i];
                    var    subAssetPath = subAssetsPath[i];// Application.dataPath + subAsset.Replace("Assets/", "/");
                    string subAssetHash = GetHashFromFile(subAssetPath);
                    subAssetHashList.Add(subAssetHash);

                    //本地ab文件存在则不打包
                    var localABPath = IPath.Combine(outpath, subAssetHash);
                    if (File.Exists(localABPath))
                    {
                        var lastItem = lastManifestConfig.GetManifestItemByHash(subAssetHash);
                        if (lastItem != null)
                        {
                            CurManifestConfig.AddItem(lastItem);
                            continue;
                        }
                    }
                    else
                    {
                        // 需要对比之前的hash
                        var lastItem = lastManifestConfig.GetManifestItemByHash(subAssetHash);
                        if (lastItem != null && lastItem.Package != "" && lastItem.Hash == subAssetHash)
                        {
                            CurManifestConfig.AddItem(lastItem);
                            continue;
                        }
                    }

                    #region 嵌套引用 - 缓存

                    var subAssetDpendList = GetDependencies(subAsset).ToList();
                    //sub dpend 2 hash
                    if (subAssetDpendList.Count > 1)
                    {
                        for (int j = 0; j < subAssetDpendList.Count; j++)
                        {
                            var sbd = subAssetDpendList[j];// Application.dataPath + subAssetDpendList[j].Replace("Assets/", "/");
                            subAssetDpendList[j] = GetHashFromFile(sbd);
                        }
                    }
                    else
                    {
                        subAssetDpendList.Clear();
                    }

                    #endregion

                    //开始设置abname
                    var ai = GetAssetImporter(subAsset);

                    ManifestItem.AssetTypeEnum @enum = ManifestItem.AssetTypeEnum.Others;
                    var    savename        = CheckAssetSaveInfo(subAsset, ref @enum);
                    string packageHashName = null;


                    #region 单ab多资源模式

                    if (IsMakePackage(subAsset, ref packageHashName))
                    {
                        #region 增量打包遇到单ab多资源

                        //增量打包时,如果遇到多包合一时,其中某个变动,剩余的也要一次性打出
//                        if (isAdditionBuild && !additionBuildPackageCache.Contains(packageHashName))
//                        {
//                            var lastAssets = lastManifestConfig.Manifest_NameKey.Values.ToList().FindAll((item) =>
//                                !string.IsNullOrEmpty(item.Package) && item.Package == packageHashName);
//                            foreach (var la in lastAssets)
//                            {
//                                //考虑增量打包时候,得补齐Runtime下的路径名
//                                var path = la.Name;
//                                if (!path.StartsWith("Assets/"))
//                                {
//                                    foreach (var key in LastAllAssetCache.Keys)
//                                    {
//                                        var p = path + ".";
//                                        if (key.Contains(p))
//                                        {
//                                            path = key;
//                                        }
//                                    }
//                                }
//
//                                //获取上次的importer
//                                var laAI = GetAssetImporter(path);
//                                if (laAI == null)
//                                {
//                                    Debug.LogError("资源不存在:" + la.Name);
//                                    continue;
//                                }
//
//                                laAI.assetBundleName = packageHashName;
//                                laAI.assetBundleVariant = "";
//                            }
//
//                            if (isAdditionBuild)
//                            {
//                                additionBuildPackageCache.Add(packageHashName);
//                            }
//                        }

                        #endregion


                        string packageName = "";
                        foreach (var item in allfileHashMap)
                        {
                            if (item.Value == packageHashName)
                            {
                                packageName = item.Key;
                                packageName = packageName.Replace(BApplication.ProjectRoot + "/", "");
                                break;
                            }
                        }


                        //保存配置
                        if (subAsset != mainAssetPath)
                        {
                            CurManifestConfig.AddItem(savename, subAssetHash, subAssetDpendList, @enum,
                                                      packageHashName);
                        }

                        ai.assetBundleName    = packageName;
                        ai.assetBundleVariant = "";

//                        ai.assetBundleName = packageHashName;
//                        ai.assetBundleVariant = "";
                    }

                    #endregion

                    #region 单ab单资源模式

                    else
                    {
                        if (subAsset != mainAssetPath)
                        {
                            CurManifestConfig.AddItem(savename, subAssetHash, subAssetDpendList, @enum);
                        }

//                        if (!subAsset.Contains("Assets/"))
//                        {
//                            ai.assetBundleName = "Assets/Resource/Runtime/" + savename;
//                            ai.assetBundleVariant = "";
//                        }
//                        else
//                        {
                        ai.assetBundleName    = subAsset;
                        ai.assetBundleVariant = "";
//                        }
//                        ai.assetBundleName = subAssetHash;
//                        ai.assetBundleVariant = "";
                    }

                    #endregion


                    changeList.Add(subAsset);
                }

                //最后保存主文件
                var    mainHash = GetHashFromFile(mainAssetPath);
                string package  = null;
                subAssetHashList.Remove(mainHash);
                if (IsMakePackage(mainAssetPath, ref package))
                {
                    //单ab包-多资源模式
                    ManifestItem.AssetTypeEnum @enum = ManifestItem.AssetTypeEnum.Others;
                    var sn = CheckAssetSaveInfo(mainAssetPath, ref @enum);
                    CurManifestConfig.AddItem(sn, mainHash, subAssetHashList, @enum, package);
                }
                else
                {
                    //单ab包-单资源模式
                    ManifestItem.AssetTypeEnum @enum = ManifestItem.AssetTypeEnum.Others;
                    var sn = CheckAssetSaveInfo(mainAssetPath, ref @enum);
                    CurManifestConfig.AddItem(sn, mainHash, subAssetHashList, @enum);
                }
            }

            //补全 [单ab多资源的配置],并将真正的hash传入
            foreach (var con in PackageConfig)
            {
                var hash = GetHashFromString(con.AssetBundleName); //多合一ab的hash是要有所有的依赖文件 hash,再hash一次
                CurManifestConfig.AddItem(con.AssetBundleName, hash, new List <string>(),
                                          ManifestItem.AssetTypeEnum.Others);
            }

            //最后检查配置
            foreach (var item in CurManifestConfig.Manifest_HashKey.Values)
            {
                for (int i = 0; i < item.Depend.Count; i++)
                {
                    var dHash = item.Depend[i];
                    //判断是否在runtime内
                    var dItem = CurManifestConfig.GetManifestItemByHash(dHash);

                    if (dItem != null)
                    {
                        if (!string.IsNullOrEmpty(dItem.Package))
                        {
                            //将非Runtime目录中的
                            item.Depend[i] = dItem.Package;
                        }
                    }
                    else
                    {
                        Debug.LogError("【资源遗失】没找到依赖项:" + dHash);
                        foreach (var v in allfileHashMap)
                        {
                            if (dHash == v.Value)
                            {
                                Debug.LogError("hash source file:" + v.Key);
                                break;
                            }
                        }
                    }
                }

                item.Depend.Remove(item.Hash);
                item.Depend = item.Depend.Distinct().ToList();
            }

            EditorUtility.ClearProgressBar();
            changeList = changeList.Distinct().ToList();
            Debug.LogFormat("<color=red>本地需要打包数量:{0}</color>", changeList.Count);
            var buildpath = string.Format("{0}/{1}_changelist.json", Application.streamingAssetsPath,
                                          target.ToString());
            File.WriteAllText(buildpath, JsonMapper.ToJson(changeList));
            Debug.Log("本地打包保存:" + buildpath);
        }