/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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 }
/// <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); }
/// <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(); }
/// <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); }