Beispiel #1
0
        /// <summary>
        /// 搜集打包信息
        /// </summary>
        public bool CollectBuildingAssets(bool isForceReCollect = false)
        {
            //初始化数据
            this.AssetTypeList = new List <string>();

            //1.生成BuildingAssetInfo信息
            BuildingAssetInfos buildingCache = null;

            //获取缓存
            if (!this.BuildParams.IsBuilding && !isForceReCollect)
            {
                buildingCache = EditorAssetInfosCache.GetBuildingAssetInfosCache();
            }

            //获取buildingAssetinfo
            this.BuildingAssetInfos = this.GetBuildingAssetInfos(buildingCache);
            //保存
            EditorAssetInfosCache.SaveBuildingAssetInfosCache(this.BuildingAssetInfos);
            //2.创建AssetRef
            foreach (var item in this.BuildingAssetInfos.AssetInfoMap)
            {
                var arf = AssetReference.CreateReference(item.Key);
                var ret = this.runtimeAssetsPathList.Contains(item.Key);
                if (ret)
                {
                    //创建runtime资源
                    this.RuntimeAssetsList.Add(arf);
                }
                else
                {
                    this.DependAssetList.Add(arf);
                }
            }


            //检测构造的数据
            var count = this.RuntimeAssetsList.Count + this.DependAssetList.Count;

            if (BuildingAssetInfos.AssetInfoMap.Count != count)
            {
                Debug.LogErrorFormat("【初始化框架资源环境】出错! buildinfo:{0} output:{1}", BuildingAssetInfos.AssetInfoMap.Count, count);

                var tmpBuildAssetsInfo = BuildingAssetInfos.Clone();
                foreach (var ra in this.RuntimeAssetsList)
                {
                    tmpBuildAssetsInfo.AssetInfoMap.Remove(ra.importFrom);
                }

                foreach (var drf in this.DependAssetList)
                {
                    tmpBuildAssetsInfo.AssetInfoMap.Remove(drf.importFrom);
                }

                Debug.Log(JsonMapper.ToJson(tmpBuildAssetsInfo.AssetInfoMap, true));

                return(false);
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// 克隆
        /// </summary>
        public BuildingAssetInfos Clone()
        {
            //手动new防止内部map,防止构造传参失效
            BuildingAssetInfos tempBuildingAssetInfos = new BuildingAssetInfos();
            //
            var json = JsonMapper.ToJson(this);
            var temp = JsonMapper.ToObject <BuildingAssetInfos>(json);

            foreach (var item in temp.AssetInfoMap)
            {
                tempBuildingAssetInfos.AssetInfoMap[item.Key] = item.Value;
            }

            return(tempBuildingAssetInfos);
        }
        /// <summary>
        /// 获取cache
        /// </summary>
        /// <returns></returns>
        static public BuildingAssetInfos GetBuildingAssetInfosCache()
        {
            //每次构建新对象返回
            if (File.Exists(PATH))
            {
                var content = File.ReadAllText(PATH);
                BuildingAssetInfos = JsonMapper.ToObject <BuildingAssetInfos>(content);
            }
            else
            {
                BuildingAssetInfos = new BuildingAssetInfos();
            }


            return(BuildingAssetInfos);
        }
Beispiel #4
0
        /// <summary>
        /// 获取改动的Assets
        /// </summary>
        public BuildingAssetInfos GetChangedAssets(BuildingAssetInfos newBuildingAssetInfos, BuildTarget buildTarget)
        {
            Debug.Log("<color=red>【增量资源】开始变动资源分析...</color>");
            BuildingAssetInfos lastBuildingAssetInfos = null;
            var buildinfoPath = IPath.Combine(this.BuildParams.OutputPath, BApplication.GetPlatformPath(buildTarget), BResources.EDITOR_ART_ASSET_BUILD_INFO_PATH);

            Debug.Log("旧资源地址:" + buildinfoPath);
            if (File.Exists(buildinfoPath))
            {
                var configContent = File.ReadAllText(buildinfoPath);
                lastBuildingAssetInfos = JsonMapper.ToObject <BuildingAssetInfos>(configContent);
            }


            //根据变动的list 刷出关联
            //I.单ab 单资源,直接重打
            //II.单ab 多资源的 整个ab都要重新打包
            if (lastBuildingAssetInfos != null && lastBuildingAssetInfos.AssetInfoMap.Count != 0)
            {
                #region 文件改动

                var changedAssetList     = new List <KeyValuePair <string, BuildingAssetInfos.AssetInfo> >();
                var changedAssetNameList = new List <string>();
                //1.找出差异文件:不一致  或者没有
                foreach (var newAssetItem in newBuildingAssetInfos.AssetInfoMap)
                {
                    if (lastBuildingAssetInfos.AssetInfoMap.TryGetValue(newAssetItem.Key, out var lastAssetItem))
                    {
                        //文件hash相同
                        if (lastAssetItem.Hash == newAssetItem.Value.Hash)
                        {
                            //依赖完全相同
                            var except = lastAssetItem.DependAssetList.Except(newAssetItem.Value.DependAssetList);
                            if (except.Count() == 0)
                            {
                                continue;
                            }
                        }
                    }

                    changedAssetList.Add(newAssetItem);
                }

                Debug.LogFormat("<color=red>【增量资源】变动文件数:{0}</color>", changedAssetList.Count);
                var changedAssetContentFiles = new List <string>();
                foreach (var item in changedAssetList)
                {
                    changedAssetContentFiles.Add(item.Key + " - " + item.Value.Hash);
                }

                Debug.Log(JsonMapper.ToJson(changedAssetContentFiles, true));

                #endregion

                #region ABName修改、颗粒度修改

                //abName修改会导致引用该ab的所有资源重新构建 才能保证正常引用关系 上线项目尽量不要有ab修改的情况
                var changedAssetBundleAssetList = new List <KeyValuePair <string, BuildingAssetInfos.AssetInfo> >();
                //AB颗粒度
                var lastABUnitMap = lastBuildingAssetInfos.PreviewAssetbundleUnit();
                var newABUnitMap  = newBuildingAssetInfos.PreviewAssetbundleUnit();
                //遍历处理
                foreach (var newAssetItem in newBuildingAssetInfos.AssetInfoMap)
                {
                    if (lastBuildingAssetInfos.AssetInfoMap.TryGetValue(newAssetItem.Key, out var lastAssetItem))
                    {
                        //AB名修改
                        if (lastAssetItem.ABName != newAssetItem.Value.ABName)
                        {
                            changedAssetBundleAssetList.Add(newAssetItem);
                        }
                        //AB 颗粒度修改
                        else
                        {
                            var lastABUnit = lastABUnitMap[lastAssetItem.ABName];
                            var newABUnit  = newABUnitMap[newAssetItem.Value.ABName];
                            //颗粒度修改
                            var except = lastABUnit.Except(newABUnit); //差集
                            if (except.Count() != 0)
                            {
                                changedAssetBundleAssetList.Add(newAssetItem);
                            }
                        }
                    }
                }


                Debug.LogFormat("<color=red>【增量资源】修改ABName(颗粒度) 文件数:{0}</color>", changedAssetBundleAssetList.Count);
                var changeABNameFiles = new List <string>();
                foreach (var item in changedAssetBundleAssetList)
                {
                    changeABNameFiles.Add(item.Key);
                }

                Debug.Log(JsonMapper.ToJson(changeABNameFiles, true));
                //引用该资源的也要重打,以保证AB正确的引用关系
                var changedCount = changedAssetBundleAssetList.Count;
                for (int i = 0; i < changedCount; i++)
                {
                    var asset  = changedAssetBundleAssetList[i];
                    var abname = asset.Value.ABName;
                    foreach (var item in newBuildingAssetInfos.AssetInfoMap)
                    {
                        if (item.Value.DependAssetList.Contains(abname))
                        {
                            changedAssetBundleAssetList.Add(item);
                        }
                    }
                }

                changedAssetBundleAssetList = changedAssetBundleAssetList.Distinct().ToList();
                //log
                Debug.LogFormat("<color=red>【增量资源】修改ABName(颗粒度)影响文件数:{0},{1}</color>", changedAssetBundleAssetList.Count, "线上修改谨慎!");
                changeABNameFiles = new List <string>();
                foreach (var item in changedAssetBundleAssetList)
                {
                    changeABNameFiles.Add(item.Key);
                }

                #endregion

                //合并
                changedAssetList.AddRange(changedAssetBundleAssetList);

                //2.依赖资源也要重新打,不然会在这次导出过程中unity默认会把依赖和该资源打到一个ab中
                foreach (var changedAsset in changedAssetList)
                {
                    //1.添加自身的ab
                    changedAssetNameList.Add(changedAsset.Value.ABName);
                    //2.添加所有依赖的ab
                    changedAssetNameList.AddRange(changedAsset.Value.DependAssetList);
                }

                changedAssetNameList = changedAssetNameList.Distinct().ToList();


                //3.搜索相同的ab name的资源,都要重新打包
                var count = changedAssetNameList.Count;
                for (int i = 0; i < count; i++)
                {
                    var rebuildABName       = changedAssetNameList[i];
                    var theSameABNameAssets = newBuildingAssetInfos.AssetInfoMap.Where((asset) => asset.Value.ABName == rebuildABName);
                    if (theSameABNameAssets != null)
                    {
                        foreach (var mainAssetItem in theSameABNameAssets)
                        {
                            //添加资源本体
                            changedAssetNameList.Add(mainAssetItem.Value.ABName);
                            //添加影响的依赖文件
                            changedAssetNameList.AddRange(mainAssetItem.Value.DependAssetList);
                        }
                    }
                }

                changedAssetNameList = changedAssetNameList.Distinct().ToList();
                //4.根据影响的ab,寻找出所有文件
                var allRebuildAssets = new List <KeyValuePair <string, BuildingAssetInfos.AssetInfo> >();
                foreach (var abname in changedAssetNameList)
                {
                    var findAssets = newBuildingAssetInfos.AssetInfoMap.Where((asset) => asset.Value.ABName == abname);
                    allRebuildAssets.AddRange(findAssets);
                }


                //去重
                var changedBuildInfo = new BuildingAssetInfos();
                foreach (var kv in allRebuildAssets)
                {
                    changedBuildInfo.AssetInfoMap[kv.Key] = kv.Value;
                }

                Debug.LogFormat("<color=red>【增量资源】总重打资源数:{0}</color>", changedBuildInfo.AssetInfoMap.Count);
                var changedFiles = new List <string>();
                foreach (var item in changedBuildInfo.AssetInfoMap)
                {
                    changedFiles.Add(item.Key);
                }

                Debug.Log(JsonMapper.ToJson(changedFiles, true));


                var ablist = changedBuildInfo.AssetInfoMap.Values.Select((a) => a.ABName).Distinct().ToList();
                Debug.LogFormat("<color=red>【增量资源】变动Assetbundle:{0}</color>", ablist.Count);
                Debug.Log(JsonMapper.ToJson(ablist, true));

                return(changedBuildInfo);
            }
            else
            {
                Debug.Log("<color=yellow>【增量资源】本地无资源,全部重打!</color>");
            }

            return(newBuildingAssetInfos);
        }
Beispiel #5
0
        /// <summary>
        ///生成Runtime下的Art.Config
        /// </summary>
        private List <AssetBundleItem> GenAssetBundleConfig(BuildingAssetInfos buildingAssetInfos, BuildAssetBundleParams buildParams, RuntimePlatform platform)
        {
            //根据buildinfo 生成加载用的 Config
            //runtime下的全部保存配置,其他的只保留一个ab名即可
            //1.导出配置
            var assetDataItemList = new List <AssetBundleItem>();

            //占位,让id和idx恒相等
            assetDataItemList.Add(new AssetBundleItem(0, null, null, -1, new int[] { }));

            //搜集runtime的 ,分两个for 让序列化后的数据更好审查
            foreach (var item in buildingAssetInfos.AssetInfoMap)
            {
                //runtime路径下,写入配置
                if (item.Key.Contains(RUNTIME_PATH, StringComparison.OrdinalIgnoreCase))
                {
                    var loadPath = GetAbsPathFormRuntime(item.Key);
                    //添加
                    var abi = new AssetBundleItem(assetDataItemList.Count, loadPath, item.Value.ABName, item.Value.Type, new int[] { });
                    // abi.EditorAssetPath = item.Key;
                    assetDataItemList.Add(abi); //.ManifestMap[key] = mi;
                    item.Value.ArtConfigIdx = abi.Id;
                }
            }

            //搜集非runtime的,进一步防止重复
            foreach (var item in buildingAssetInfos.AssetInfoMap)
            {
                //非runtime的只需要被索引AB
                if (!item.Key.Contains(RUNTIME_PATH, StringComparison.OrdinalIgnoreCase))
                {
                    var ret = assetDataItemList.FirstOrDefault((ab) => ab.AssetBundlePath == item.Value.ABName);
                    if (ret == null) //不保存重复内容
                    {
                        var abi = new AssetBundleItem(assetDataItemList.Count, null, item.Value.ABName, item.Value.Type, new int[] { });
                        // abi.EditorAssetPath = item.Key;
                        assetDataItemList.Add(abi);
                        item.Value.ArtConfigIdx = abi.Id;
                    }
                }
            }


            //将depend替换成Id,减少序列化数据量
            foreach (var assetbundleData in assetDataItemList)
            {
                if (!string.IsNullOrEmpty(assetbundleData.LoadPath))
                {
                    //dependAsset 替换成ID
                    var buildAssetData = buildingAssetInfos.AssetInfoMap.Values.FirstOrDefault((asset) => asset.ABName == assetbundleData.AssetBundlePath);
                    for (int i = 0; i < buildAssetData.DependAssetList.Count; i++)
                    {
                        var dependAssetName = buildAssetData.DependAssetList[i];
                        //寻找保存列表中依赖的id(可以认为是下标)
                        var dependAssetBuildData = assetDataItemList.FirstOrDefault((asset) => asset.AssetBundlePath == dependAssetName);
                        //向array添加元素,editor 略冗余,目的是为了保护 runtime 数据源readonly
                        var templist = assetbundleData.DependAssetIds.ToList();
                        templist.Add(dependAssetBuildData.Id);
                        assetbundleData.DependAssetIds = templist.ToArray();
                    }
                }
            }


            #region 检查生成的数据

            //检查config是否遗漏
            foreach (var assetDataItem in buildingAssetInfos.AssetInfoMap)
            {
                var ret = assetDataItemList.Find((abi) => abi.AssetBundlePath == assetDataItem.Value.ABName);
                if (ret == null)
                {
                    Debug.LogError("【生成配置】ab配置遗漏 - " + assetDataItem.Key + " ab:" + assetDataItem.Value.ABName);
                }
            }

            #endregion


            //
            return(assetDataItemList);
        }
Beispiel #6
0
        /// <summary>
        /// 合并ABname
        /// </summary>
        public void MergeABName(BuildingAssetInfos buildingAssetInfos)
        {
            #region 整理依赖关系

            //1.把依赖资源替换成AB Name,
            foreach (var mainAsset in buildingAssetInfos.AssetInfoMap.Values)
            {
                // if (mainAsset.ABName.Equals("assets/resource/runtime/shader/allshaders.shadervariants", StringComparison.OrdinalIgnoreCase))
                // {
                //     Debug.Log("xx");
                // }
                //
                for (int i = 0; i < mainAsset.DependAssetList.Count; i++)
                {
                    var dependAssetName = mainAsset.DependAssetList[i];
                    if (buildingAssetInfos.AssetInfoMap.TryGetValue(dependAssetName, out var dependAssetData))
                    {
                        //替换成真正AB名
                        if (!string.IsNullOrEmpty(dependAssetData.ABName))
                        {
                            mainAsset.DependAssetList[i] = dependAssetData.ABName;
                        }
                    }
                    else
                    {
                        Debug.Log("【AssetbundleV2】资源整理出错: " + dependAssetName);
                    }
                }

                //去重,移除自己
                mainAsset.DependAssetList = mainAsset.DependAssetList.Distinct().ToList();
                mainAsset.DependAssetList.Remove(mainAsset.ABName);
            }

            //2.按规则纠正ab名
            //使用guid 作为ab名
            foreach (var mainAsset in buildingAssetInfos.AssetInfoMap)
            {
                var guid = AssetDatabase.AssetPathToGUID(mainAsset.Value.ABName);
                if (!string.IsNullOrEmpty(guid))
                {
                    mainAsset.Value.ABName = guid;
                }
                else
                {
                    Debug.LogError("获取GUID失败:" + mainAsset.Value.ABName);
                }

                for (int i = 0; i < mainAsset.Value.DependAssetList.Count; i++)
                {
                    var dependAssetPath = mainAsset.Value.DependAssetList[i];

                    guid = AssetDatabase.AssetPathToGUID(dependAssetPath);
                    if (!string.IsNullOrEmpty(guid))
                    {
                        mainAsset.Value.DependAssetList[i] = guid;
                    }
                    else
                    {
                        Debug.LogError("获取GUID失败:" + dependAssetPath);
                    }
                }
            }

            #endregion
        }
Beispiel #7
0
        /// <summary>
        /// 打包Asset Bundle
        /// </summary>
        /// <param name="buildingAssetInfos"></param>
        /// <param name="buildParams"></param>
        /// <param name="platform"></param>
        private void BuildAssetBundle(List <AssetBundleItem> assetBundleItemList, BuildingAssetInfos buildingAssetInfos, BuildAssetBundleParams buildParams, RuntimePlatform platform)
        {
            //----------------------------开始设置build ab name-------------------------------
            //根据传进来的资源,设置AB name
            foreach (var buildInfoItem in buildingAssetInfos.AssetInfoMap)
            {
                var assetPath = buildInfoItem.Key;
                var assetData = buildInfoItem.Value;
                //设置ab name
                var ai = GetAssetImporter(assetPath);
                if (ai)
                {
                    ai.SetAssetBundleNameAndVariant(assetData.ABName, null);
                }
            }


            //----------------------------生成AssetBundle-------------------------------
            var    platformOutputPath = Path.Combine(buildParams.OutputPath, BApplication.GetPlatformPath(platform));
            string abOutputPath       = IPath.Combine(platformOutputPath, BResources.ART_ASSET_ROOT_PATH);

            if (!Directory.Exists(abOutputPath))
            {
                Directory.CreateDirectory(abOutputPath);
            }

            //配置
            var buildTarget = BApplication.GetBuildTarget(platform);
            BuildAssetBundleOptions buildOpa =
                BuildAssetBundleOptions.ChunkBasedCompression |                                                                       //压缩
                BuildAssetBundleOptions.DeterministicAssetBundle |                                                                    //保证一致
                //BuildAssetBundleOptions.DisableWriteTypeTree| //关闭TypeTree
                BuildAssetBundleOptions.DisableLoadAssetByFileName | BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension; //关闭使用filename加载

            //关闭TypeTree
            var buildAssetConf = BDEditorApplication.BDFrameworkEditorSetting?.BuildAssetBundleSetting;

            if (buildAssetConf.IsDisableTypeTree)
            {
                buildOpa |= BuildAssetBundleOptions.DisableWriteTypeTree; //关闭TypeTree
            }


            UnityEditor.BuildPipeline.BuildAssetBundles(abOutputPath, buildOpa, buildTarget);
            Debug.LogFormat("【编译AssetBundle】 output:{0} ,buildTarget:{1}", abOutputPath, buildTarget.ToString());



            //3.检测本地Assetbundle
            // allAbList = Directory.GetFiles(abOutputPath, "*", SearchOption.AllDirectories);
            // foreach (var abpath in allAbList)
            // {
            //     if (abpath.Contains("."))
            //     {
            //         continue;
            //     }
            //
            //     var depend = AssetDatabase.GetAssetBundleDependencies(abpath,true);
            // }

            GlobalAssetsHelper.GenBasePackageAssetBuildInfo(buildParams.OutputPath, platform);
        }
Beispiel #8
0
        /// <summary>
        /// 开始构建AB
        /// </summary>
        public void StartBuildAssetBundle(BuildTarget buildTarget)
        {
            //-----------------------开始打包AssetBundle逻辑---------------------------
            Debug.Log("【BuildAssetbundle】执行Build...");
            //设置编辑器状态
            BDEditorApplication.EditorStatus = BDFrameworkEditorStatus.BuildAssetBundle;
            var    platform           = BApplication.GetRuntimePlatform(buildTarget);
            var    platformOutputPath = IPath.Combine(BuildParams.OutputPath, BApplication.GetPlatformPath(platform));
            string abOutputPath       = IPath.Combine(platformOutputPath, BResources.ART_ASSET_ROOT_PATH);

            //--------------------------------开始打包----------------------------------
            //1.打包
            Debug.Log("<color=green>----->1.进入打包逻辑</color>");
            //整理abname
            this.MergeABName(BuildingAssetInfos);
            //对比差异文件
            var changedAssetsInfo = GetChangedAssets(BuildingAssetInfos, buildTarget);
            //生成artconfig
            var assetbundleItemList = this.GenAssetBundleConfig(BuildingAssetInfos, BuildParams, platform);

            //打包
            AssetDatabase.StartAssetEditing(); //禁止自动导入
            {
                this.BuildAssetBundle(assetbundleItemList, changedAssetsInfo, BuildParams, platform);
            }
            AssetDatabase.StopAssetEditing(); //恢复自动导入


            //2.清理
            Debug.Log("<color=green>----->2.清理旧ab</color>");
            //移除所有的ab
            RemoveAllAssetbundleName();
            //删除本地没有的资源
            var allABList = Directory.GetFiles(abOutputPath, "*", SearchOption.AllDirectories).Where((p) => string.IsNullOrEmpty(Path.GetExtension(p)));

            foreach (var abpath in allABList)
            {
                var abname = Path.GetFileName(abpath);
                var ret    = assetbundleItemList.FirstOrDefault((abdata) => abdata.AssetBundlePath == abname);
                if (ret == null)
                {
                    //
                    File.Delete(abpath);
                    File.Delete(abpath + ".manifest");
                    //
                    var path = AssetDatabase.GUIDToAssetPath(abname);
                    Debug.Log("【删除旧ab:】" + abname + "  -  " + path);
                }
            }



            //3.BuildInfo配置处理
            Debug.Log("<color=green>----->3.BuildInfo相关生成</color>");
            //设置ab的hash
            foreach (var abi in assetbundleItemList)
            {
                if (string.IsNullOrEmpty(abi.AssetBundlePath))
                {
                    continue;
                }

                var abpath = IPath.Combine(platformOutputPath, BResources.ART_ASSET_ROOT_PATH, abi.AssetBundlePath);
                var hash   = FileHelper.GetMurmurHash3(abpath);
                abi.Hash = hash;
            }

            //获取上一次打包的数据,跟这次打包数据合并
            var configPath = IPath.Combine(platformOutputPath, BResources.ART_ASSET_CONFIG_PATH);

            if (File.Exists(configPath))
            {
                var lastAssetbundleItemList = CsvSerializer.DeserializeFromString <List <AssetBundleItem> >(File.ReadAllText(configPath));
                foreach (var newABI in assetbundleItemList)
                {
                    if (string.IsNullOrEmpty(newABI.AssetBundlePath))
                    {
                        continue;
                    }

                    // //判断是否在当前打包列表中
                    // var ret = changedAssetsInfo.AssetDataMaps.Values.FirstOrDefault((a) => a.ABName.Equals(newABI.AssetBundlePath, StringComparison.OrdinalIgnoreCase));

                    var lastABI = lastAssetbundleItemList.FirstOrDefault((last) =>
                                                                         newABI.AssetBundlePath.Equals(last.AssetBundlePath, StringComparison.OrdinalIgnoreCase)); //AB名相等
                    //&& newABI.Hash == last.Hash); //hash相等
                    //没重新打包,则用上一次的mix信息
                    if (lastABI != null && lastABI.Hash == newABI.Hash)
                    {
                        newABI.Mix = lastABI.Mix;
                    }
                    //否则mix = 0
                }
            }

            //保存artconfig.info
            var csv = CsvSerializer.SerializeToString(assetbundleItemList);

            FileHelper.WriteAllText(configPath, csv);


            //保存BuildInfo配置
            var buildinfoPath = IPath.Combine(platformOutputPath, BResources.EDITOR_ART_ASSET_BUILD_INFO_PATH);
            //缓存buildinfo
            var json = JsonMapper.ToJson(BuildingAssetInfos, true);

            FileHelper.WriteAllText(buildinfoPath, json);


            //4.备份Artifacts
            //this.BackupArtifacts(buildTarget);

            //5.检测本地的Manifest和构建预期对比
            Debug.Log("<color=green>----->5.校验AB依赖</color>");
            var abRootPath       = IPath.Combine(BuildParams.OutputPath, BApplication.GetPlatformPath(platform), BResources.ART_ASSET_ROOT_PATH);
            var previewABUnitMap = BuildingAssetInfos.PreviewAssetbundleUnit();
            var manifestList     = Directory.GetFiles(abRootPath, "*.manifest", SearchOption.AllDirectories);

            //解析 manifestBuildParams.OutputPath
            for (int i = 0; i < manifestList.Length; i++)
            {
                var manifest = manifestList[i].Replace("\\", "/");


                if (manifest.Equals(abRootPath + ".manifest"))
                {
                    continue;
                }

                var           lines = File.ReadLines(manifest);
                List <string> manifestDependList = new List <string>();
                bool          isStartRead        = false;
                foreach (var line in lines)
                {
                    if (!isStartRead && line.Equals("Assets:"))
                    {
                        isStartRead = true;
                    }
                    else if (line.Contains("Dependencies:"))
                    {
                        break;
                    }
                    else if (isStartRead)
                    {
                        var file = line.Replace("- ", "");
                        manifestDependList.Add(file.ToLower());
                    }
                }

                //对比依赖
                var abname = Path.GetFileNameWithoutExtension(manifest);
                if (abname.Equals(BResources.ART_ASSET_ROOT_PATH, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                previewABUnitMap.TryGetValue(abname, out var previewABDependList);
                if (previewABDependList == null)
                {
                    Debug.LogError("【AssetbundleV2-验证】本地ab的配置不不存在:" + abname);
                    Debug.LogError("path:" + AssetDatabase.GUIDToAssetPath(abname));
                }
                else
                {
                    //求差集
                    var except = manifestDependList.Except(previewABDependList);
                    if (except.Count() != 0)
                    {
                        var local   = JsonMapper.ToJson(manifestDependList, true);
                        var preview = JsonMapper.ToJson(previewABDependList, true);
                        Debug.LogError($"【AssetbundleV2-验证】本地AssetBundle依赖与预期不符:\n 本地:{local} \n 预期:{preview}");
                    }
                }
            }


            //6.资源混淆
            Debug.Log("<color=green>----->6.混淆AB</color>");
            if (BDEditorApplication.BDFrameworkEditorSetting.BuildAssetBundleSetting.IsEnableObfuscation)
            {
                AssetBundleEditorToolsV2.MixAssetBundle(BuildParams.OutputPath, platform);
            }


            //恢复编辑器状态
            BDEditorApplication.EditorStatus = BDFrameworkEditorStatus.Idle;
            //BD生命周期触发
            BDFrameworkPipelineHelper.OnEndBuildAssetBundle(this);


            //GenAssetBundleItemCacheList = abConfigList.ToList();
        }
Beispiel #9
0
        /// <summary>
        ///  获取BuildAssetsInfo
        /// </summary>
        /// <returns></returns>
        private BuildingAssetInfos GetBuildingAssetInfos(BuildingAssetInfos buildingInfoCache = null)
        {
            var retBuildingInfo = new BuildingAssetInfos();
            //开始
            var sw = new Stopwatch();

            sw.Start();

            retBuildingInfo.Time = DateTime.Now.ToShortDateString();
            int id = 0;

            //1.获取runtime资产
            runtimeAssetsPathList = GetRuntimeAssetsPath();
            //2.搜集所有的依赖资产
            var allAssetList = new List <string>();

            allAssetList.AddRange(runtimeAssetsPathList);
            //获取所有依赖
            for (int i = 0; i < runtimeAssetsPathList.Count; i++)
            {
                var runtimeAsset = runtimeAssetsPathList[i];
                BuildingAssetInfos.AssetInfo assetInfo = null;
                //从缓存取依赖
                buildingInfoCache?.AssetInfoMap.TryGetValue(runtimeAsset, out assetInfo);
                if (assetInfo != null)
                {
                    allAssetList.AddRange(assetInfo.DependAssetList);
                }
                else
                {
                    var dependList = this.GetDependAssetList(runtimeAsset);
                    allAssetList.AddRange(dependList);
                }
            }
            //去重
            allAssetList = allAssetList.Distinct().ToList();
            //用所有资源构建AssetMap
            foreach (var assetPath in allAssetList)
            {
                //防止重复
                if (retBuildingInfo.AssetInfoMap.ContainsKey(assetPath))
                {
                    continue;
                }

                //优先从缓存获取
                var assetInfo = buildingInfoCache?.GetNewInstanceAssetInfo(assetPath);
                if (assetInfo == null)
                {
                    //构建资源信息
                    assetInfo = CreateAssetInfo(assetPath);
                }

                //添加
                assetInfo.Id = retBuildingInfo.AssetInfoMap.Count + 1;
                retBuildingInfo.AssetInfoMap[assetPath] = assetInfo;
            }

            //TODO AB依赖关系纠正
            /// 已知Unity,bug/设计缺陷:
            ///   1.依赖接口,中会携带自己
            ///   2.如若a.png、b.png 依赖 c.atlas,则abc依赖都会是:a.png 、b.png 、 a.atlas
            // foreach (var asset in buildingAssetInfos.AssetDataMaps)
            // {
            //     //依赖中不包含自己
            //     //asset.Value.DependAssetList.Remove(asset.Key);
            // }
            sw.Stop();
            Debug.LogFormat("【GenBuildInfo】耗时:{0}ms.", sw.ElapsedMilliseconds);
            return(retBuildingInfo);
        }
        /// <summary>
        /// 保存缓存信息
        /// </summary>
        /// <returns></returns>
        static public void SaveBuildingAssetInfosCache(BuildingAssetInfos buildingAssetInfos)
        {
            var content = JsonMapper.ToJson(buildingAssetInfos, true);

            FileHelper.WriteAllText(PATH, content);
        }