public static bool BuildAssetsBundle(BuildAssetConfig assetConfig = null) { if (null == assetConfig) { assetConfig = new BuildAssetConfig() { }; } BuildAssetsBundle(assetConfig, buildItemConfig, Path.Combine(Application.dataPath, "data")); return(true); }
private static void BuildAssetsBundle(BuildAssetConfig assetConfig, BuildItemConfig[] buildItemConfig, string rootPath) { RemoveAllAssetBundleNames(); GenerateBundles(buildItemConfig, rootPath); if (assetConfig.isUpdate) { GenerateUpdatePackages(assetConfig); } else { Logger.LogError("copy assets"); CopyAsset(BuildOutputPath, Application.streamingAssetsPath); AssetDatabase.ImportAsset("Assets/StreamingAssets/data", ImportAssetOptions.ForceUpdate); } }
private static void GenerateUpdatePackages(BuildAssetConfig assetConfig) { ResourceConfig oldConfig = LoadFileFromPackage(assetConfig.packagePath, VERFILE_CONF_PATH); ResourceConfig oldUpdateConfig = null; if (string.IsNullOrEmpty(assetConfig.updatePackagePath)) { oldUpdateConfig = new ResourceConfig(); } else { oldUpdateConfig = LoadFileFromPackage(assetConfig.updatePackagePath, UPDATELIST_CONF_PATH); } // old files md5 Dictionary <string, string> oldFileMd5 = new Dictionary <string, string>(); foreach (var item in oldConfig.resource.patchLst) { oldFileMd5[item.file] = item.md5; } foreach (var item in oldUpdateConfig.resource.patchLst) { oldFileMd5[item.file] = item.md5; } // load new verfile and caculate new verfile md5 AssetBundle newVerfileBundle = null; ResourceConfig verfileConfig = new ResourceConfig(); string verfileHashValue = string.Empty; try { byte[] verfileBytes = File.ReadAllBytes(Path.Combine(BuildOutputPath, VERFILE_CONF_PATH)); newVerfileBundle = AssetBundle.LoadFromMemory(verfileBytes); string verfileText = newVerfileBundle.LoadAsset <TextAsset>(newVerfileBundle.GetAllAssetNames()[0]).text; verfileConfig.Initialize(verfileText); ResourceConfig tempVersionJson = new ResourceConfig(); tempVersionJson.Initialize(verfileText); tempVersionJson.resource.patchLst.RemoveAll((item) => { return(item.file.Contains("verfile") || item.file.Contains("updatelist")); }); verfileHashValue = Utils.HashToMd5(Pathfinding.Serialization.JsonFx.JsonWriter.Serialize(tempVersionJson.resource)); } finally { if (null != newVerfileBundle) { newVerfileBundle.Unload(false); newVerfileBundle = null; } } ResourceConfig updateConfig = new ResourceConfig(); updateConfig.resource.hashValue = verfileHashValue; ConfResourceItem verfileItem = null; foreach (var newItem in verfileConfig.resource.patchLst) { if (newItem.file.Contains("updatelist")) { continue; } if (newItem.file.Contains("verfile")) { newItem.md5 = Utils.FileToMd5(Path.Combine(BuildOutputPath, VERFILE_CONF_PATH)); verfileItem = newItem; continue; } var oldItemMd5 = string.Empty; oldFileMd5.TryGetValue(newItem.file, out oldItemMd5); // add or modify if (string.IsNullOrEmpty(oldItemMd5) || oldItemMd5 != newItem.md5) { updateConfig.resource.patchLst.Add(newItem); } } if (updateConfig.resource.patchLst.Count <= 0) { updateConfig.resource.hashValue = oldUpdateConfig.resource.hashValue; } else { updateConfig.resource.patchLst.Add(verfileItem); } // set need copy asset map Dictionary <string, string> needCopyMap = new Dictionary <string, string>(); foreach (var item in updateConfig.resource.patchLst) { needCopyMap.Add(item.file, Path.Combine(BuildOutputPath, item.file)); } needCopyMap[UPDATELIST_CONF_PATH] = Path.Combine(BuildOutputPath, UPDATELIST_CONF_PATH); // add old update list to new, but don't need to copy foreach (var item in oldUpdateConfig.resource.patchLst) { // this is the old update list if (item.file.Contains("updatelist")) { continue; } if (updateConfig.resource.patchLst.FindAll(fileItem => { return(fileItem.file == item.file); }).Count <= 0) { updateConfig.resource.patchLst.Add(item); } } string updateListConfigText = SerializeJsonFile(updateConfig.resource, UPDATELIST_JSON_PATH); string tempDirectory = Path.Combine(Application.dataPath, "../" + FileUtil.GetUniqueTempPathInProject()); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } AssetBundleBuild[] buildMap = new AssetBundleBuild[] { new AssetBundleBuild() { assetBundleName = UPDATELIST_CONF_PATH, assetNames = new string[] { "Assets/data/conf/updatelist.json" } }, }; BuildPipeline.BuildAssetBundles(tempDirectory, buildMap, BuildAssetBundleOptions.ChunkBasedCompression, CurrentBuildTarget); CopyFileEx(Path.Combine(tempDirectory, UPDATELIST_CONF_PATH), Path.Combine(BuildOutputPath, UPDATELIST_CONF_PATH)); using (MemoryStream compressed = new MemoryStream()) { using (ZipOutputStream compressor = new ZipOutputStream(compressed)) { int count = 0; try { compressor.SetComment(updateListConfigText); } catch { compressor.SetComment(string.Format("hash:{0}", updateConfig.resource.hashValue)); } foreach (var fileKV in needCopyMap) { string file = fileKV.Value; ZipEntry entry = new ZipEntry(fileKV.Key); entry.DateTime = new System.DateTime(); entry.DosTime = 0; compressor.PutNextEntry(entry); if (Directory.Exists(file)) { continue; } byte[] bytes = File.ReadAllBytes(file); int offset = 0; compressor.Write(bytes, offset, bytes.Length - offset); EditorUtility.DisplayProgressBar("Generate update files", string.Format("Add:\t{0}", file), (++count % needCopyMap.Count)); } compressor.Finish(); compressor.Flush(); byte[] fileBytes = new byte[compressed.Length]; Array.Copy(compressed.GetBuffer(), fileBytes, compressed.Length); string fileName = string.Format("{0}_{1}_{2}_{3}.zip", Path.GetFileNameWithoutExtension(assetConfig.packagePath), DateTime.Now.ToString("yyyy.MM.dd_HH.mm.s"), Utils.HashToMd5(fileBytes), updateConfig.resource.hashValue); string filePath = Path.Combine(UpdateBuildPath, fileName); File.WriteAllBytes(filePath, fileBytes); if (null != assetConfig.successCallback) { assetConfig.successCallback(filePath); } } } EditorUtility.ClearProgressBar(); }