public AssetBundleLoader CreateAssetBundleLoader(string assetFileName, object param, bool loadMulti = false, bool isAsync = false) { AssetBundleLoader bundleLoader = null; string abFile = assetFileName.ToLower(); if (loaderCacheDic.ContainsKey(abFile)) { bundleLoader = loaderCacheDic[abFile]; bundleLoader.isAsync = isAsync; if (null != bundleLoader.bundleInfo) { bundleLoader.bundleInfo.param = param; } } else { ConfResourceItem resItem = null; #if UNITY_EDITOR && !AB_MODE bundleLoader = new EditorModeAssetBundleLoader(loadMulti, OnLoadComplete, OnLoadError); #else resItem = ConfigManager.Instance.resourceConfig.GetResourceItem(abFile); bundleLoader = new MobileAssetBundleLoader(OnLoadComplete, OnLoadError); bundleLoader.onDepLoadCompleted = OnDepLoadComplete; #endif bundleLoader.bundleData = resItem; bundleLoader.bundleName = abFile; bundleLoader.isAsync = isAsync; bundleLoader.param = param; loaderCacheDic.Add(abFile, bundleLoader); } return(bundleLoader); }
public ConfResourceItem GetResourceItem(string fileName) { ConfResourceItem resItem = null; resourceDic.TryGetValue(fileName, out resItem); return(resItem); }
private IEnumerator StartUnzipAsset() { ResourceConfig resourceConfig = new ResourceConfig(); using (WWW www = new WWW(verfilePath)) { yield return(www); if (null != www.error) { Logger.LogError("load verfile failed"); yield break; } TextAsset verfileText = www.assetBundle.LoadAsset <TextAsset>("verfile"); resourceConfig.Initialize(verfileText.text); www.assetBundle.Unload(false); } List <KeyValuePair <string, string> > downLoadList = new List <KeyValuePair <string, string> >(); for (int index = 0; index < resourceConfig.resource.patchLst.Count; ++index) { ConfResourceItem item = resourceConfig.resource.patchLst[index]; downLoadList.Add(new KeyValuePair <string, string>(GameConstant.AssetBundleBasePath + item.file, GameConstant.PersistentDataPath + item.file)); } int fileCount = 0; for (int index = 0; index < downLoadList.Count; ++index) { KeyValuePair <string, string> item = downLoadList[index]; AssetBundleManager.Instance.DownloadAssetAsync(item.Key, item.Value, (abInfo) => { ++fileCount; //Logger.LogError("unzip progress = " + (float)fileCount / downLoadList.Count); }); } while (fileCount < downLoadList.Count) { yield return(null); } Logger.LogError("unzip complete"); yield return(StartCoroutine(CheckAssetUpdate())); }
private void InitData() { resourceDic.Clear(); for (int index = 0; index < resource.patchLst.Count; ++index) { ConfResourceItem item = resource.patchLst[index]; if (string.IsNullOrEmpty(item.file)) { Logger.LogError("the resource file name is empty"); continue; } if (resourceDic.ContainsKey(item.file)) { Logger.LogError("the file is exists file = " + item.file); continue; } resourceDic.Add(item.file, item); } }
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(); }
private static void GenerateBundles(BuildItemConfig[] buildItemConfig, string rootPath) { EditorUtility.DisplayProgressBar("Generate Resource", "Gather resources...", 1); List <AssetBundleBuild> resourcesLst = new List <AssetBundleBuild>(); foreach (var item in buildItemConfig) { string bundleRootPath = Path.Combine(rootPath, item.name); string[] entries = item.isFolder ? Directory.GetDirectories(bundleRootPath, item.filter, item.recursion ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly) : Directory.GetFiles(bundleRootPath, item.filter, item.recursion ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); foreach (var tempEntry in entries) { string entry = tempEntry.Replace("\\", "/"); if (!item.isFolder) { string extension = Path.GetExtension(entry).ToLower(); if (extension == ".meta" || extension == ".ds_store") { continue; } } string path = entry; int subIndex = path.IndexOf("Assets"); path = path.Substring(subIndex + 7); if (!item.isFolder) { path = path.Substring(0, path.LastIndexOf('.')); } List <string> assetLst = new List <string>(); if (!item.isFolder) { assetLst.Add(entry.Substring(subIndex)); } else { string[] files = Directory.GetFiles(entry); foreach (var file in files) { string extension = Path.GetExtension(file).ToLower(); if (extension == ".meta" || extension == ".ds_store") { continue; } assetLst.Add(file.Substring(subIndex).Replace("\\", "/")); } assetLst.Sort((lhs, rhs) => { return(lhs.CompareTo(rhs)); }); } resourcesLst.Add(new AssetBundleBuild() { assetBundleName = string.Format("{0}.{1}", path, item.name), assetNames = assetLst.ToArray() }); } } EditorUtility.DisplayProgressBar("Generate resource", "Build resources...", 1); resourcesLst.Sort((lhs, rhs) => { return(lhs.assetBundleName.CompareTo(rhs.assetBundleName)); }); BuildPipeline.BuildAssetBundles(BuildOutputPath, resourcesLst.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, CurrentBuildTarget); AssetBundleManifest manifest = LoadManifest(); string[] assets = manifest.GetAllAssetBundles(); EditorUtility.DisplayProgressBar("Generate resource", "Create verfile...", 1); ResourceConfig resource = new ResourceConfig(); foreach (var asset in assets) { ConfResourceItem resItem = new ConfResourceItem(); string fullPath = Path.Combine(BuildOutputPath, asset); FileInfo fileInfo = new FileInfo(fullPath); int fileSize = 0; if (fileInfo.Exists) { fileSize = Mathf.CeilToInt(fileInfo.Length / 1024.0f); } else { Debug.LogError("the file is not exists file = " + asset); } resItem.file = asset; resItem.size = fileSize; resItem.md5 = Utils.FileToMd5(fullPath); resItem.assetType = AssetBundleExportType.Alone; if (!asset.EndsWith(".field")) { string[] dependencies = manifest.GetAllDependencies(asset); foreach (var depend in dependencies) { resItem.dependencies.Add(depend); } } resource.resource.patchLst.Add(resItem); } #region generate verfile SerializeJsonFile(resource.resource, VERFILE_JSON_PATH); #endregion #region generate update file list ResourceConfig updateList = new ResourceConfig(); SerializeJsonFile(updateList.resource, UPDATELIST_JSON_PATH); #endregion string tempDirectory = Path.Combine(Application.dataPath, "../" + FileUtil.GetUniqueTempPathInProject()); if (!Directory.Exists(tempDirectory)) { Directory.CreateDirectory(tempDirectory); } AssetBundleBuild[] buildMap = new AssetBundleBuild[] { new AssetBundleBuild() { assetBundleName = VERFILE_CONF_PATH, assetNames = new string[] { "Assets/data/conf/verfile.json" } }, 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, VERFILE_CONF_PATH), Path.Combine(BuildOutputPath, VERFILE_CONF_PATH)); CopyFileEx(Path.Combine(tempDirectory, UPDATELIST_CONF_PATH), Path.Combine(BuildOutputPath, UPDATELIST_CONF_PATH)); EditorUtility.ClearProgressBar(); }