/// <summary> /// Checks the version. /// </summary> /// <returns><c>true</c>, if version was checked, <c>false</c> otherwise.</returns> private static bool CheckResourceVersion(bool checkResVersion = false) { // 没有新版本文件 if (mNewVersionCsv == null || mNewVersionCsv.rows == null) { return(false); } // 如果本地版本文件为空 if (mVersionCsv == null || mVersionCsv.rows == null) { return(true); } // 不需要检查ResVersion // 只有在客户端启动尝试解压缩的时候才需要 if (!checkResVersion) { return(true); } // 读取版本文件资源版本号 CsvRow newData = mNewVersionCsv.FindByKey(RES_VERSION_NAME); if (newData == null) { return(false); } // 获取本地资源版本信息 CsvRow resData = mVersionCsv.FindByKey(RES_VERSION_NAME); if (resData == null) { return(true); } // 对比版本 return(string.Compare(newData.Query <string>("md5"), resData.Query <string>("md5")) > 0); }
/// <summary> /// 获取资源所在AssetBundle的名字 /// </summary> public static string GetAssetBundleName(string path) { // 查找版本树,确认该资源是否是版本树上的资源 CsvRow data = mResourceDictCsv.FindByKey(path); // 该资源是内部资源 if (data == null) { return(string.Empty); } // 返回该资源所属assetbundle return(data.Query <string>("bundle")); }
/// <summary> /// 发布资源 /// </summary> private static void DoBuildPublish(BuildTarget target, string resVersion, bool isNewAssets, string channel) { string rootPath = GetABRootPath(target, channel); string publishPath = string.Format("{0}/PublishAssetBundles/", rootPath); string abPath = string.Format("{0}/AssetBundles/", rootPath); string patchPath = string.Format("{0}/PatchAssetBundles/", rootPath); string encryptPath = string.Format("{0}/EncryptAssetBundles/", rootPath); // 如果需要重新打包资源则删除原来的版本文件 if (isNewAssets) { FileMgr.DeleteDirectory(abPath); } // ab路径是否存在,不存在则创建一个 DirectoryInfo abInfo = new DirectoryInfo(abPath); if (!abInfo.Exists) { abInfo.Create(); } // 确保目录存在 FileMgr.DeleteDirectory(encryptPath); FileMgr.CreateDirectory(encryptPath); FileMgr.DeleteDirectory(publishPath); FileMgr.CreateDirectory(publishPath); FileMgr.DeleteDirectory(patchPath); FileMgr.CreateDirectory(patchPath); BuildAssetBundleOptions opt = BuildAssetBundleOptions.DeterministicAssetBundle | // 保证同样的资源多次打包出的assetbundle相同 BuildAssetBundleOptions.UncompressedAssetBundle; // 不压缩资源,我们会压缩,然后在目标平台解压缩,最后使用的是没有压缩的资源,保证资源快速加载 // AssetBundle打包,Unity5.x之后都是用这个方法打包,而且还会自动生成依赖关系 AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(abPath, opt, target); // 载入旧版本树 CsvFile oldVersionCsv = LoadVersion(abPath); // 生成资源映射表 GenResourceDictFile(abPath, manifest); //// 加密ab资源包 DoEncryptAssetBundle(encryptPath, abPath, manifest); // 收集需要发布的ab资源包 Dictionary <string, string> newABVersion = DoCollectNewABVersion(encryptPath, manifest); // 资源大小映射表 Dictionary <string, List <object> > versionItemInfo = new Dictionary <string, List <object> >(); // 是否需要更新标识 bool isABChanged = false; byte[] unzipBuf; byte[] buf; // 发布资源 foreach (string abName in newABVersion.Keys) { // 获取旧版本信息 CsvRow data = oldVersionCsv.FindByKey(abName); if ((data != null) && string.Equals(data.Query <string>("md5"), newABVersion[abName])) { // 添加到列表中 versionItemInfo.Add(abName, new List <object>() { newABVersion[abName], data.Query <int>("unzip_size"), data.Query <int>("zip_size") }); continue; } // 标识数据已经变化了 isABChanged = true; // 取得未压缩大小 unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, abName)); if (unzipBuf.Length == 0) { NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, abName)); continue; } NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, abName) }, string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName])); // 读取文件 buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName])); if (buf.Length == 0) { NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, abName)); continue; } // 添加到列表中 versionItemInfo.Add(abName, new List <object>() { newABVersion[abName], unzipBuf.Length, buf.Length }); } // 如果ab资源没有变化, 不处理 if (isABChanged) { string resourceDictPath = string.Format("{0}{1}", encryptPath, "resource_dict.bytes"); // 发布资源到发布资源目录 string md5 = NIEditorUtility.GetFileMD5(resourceDictPath); // 取得未压缩大小 unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, "resource_dict.bytes")); if (unzipBuf.Length == 0) { NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, "resource_dict.bytes")); return; } NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, "resource_dict.bytes") }, string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5)); // 读取文件 buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5)); if (buf.Length == 0) { NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, "resource_dict.bytes")); return; } // 添加到列表中 versionItemInfo.Add("resource_dict.bytes", new List <object>() { md5, unzipBuf.Length, buf.Length }); } bool isPatchChanged = false; Dictionary <string, string> abPatchDic = new Dictionary <string, string>(); // 生成压缩patch文件 Dictionary <string, string> newPatchVersion = GenPatchFiles(patchPath, encryptPath, versionItemInfo, ref abPatchDic); // 发布资源 foreach (string patchName in newPatchVersion.Keys) { // 获取旧版本信息 CsvRow data = oldVersionCsv.FindByKey(patchName); if ((data != null) && string.Equals(data.Query <string>("md5"), newPatchVersion[patchName])) { versionItemInfo.Add(patchName, new List <object>() { data.Query <string>("md5"), 0, data.Query <int>("zip_size") }); continue; } // 标识数据已经变化了 isPatchChanged = true; string filePath = string.Format("{0}{1}_{2}.zip", patchPath, patchName, newPatchVersion[patchName]); // 读取文件 buf = File.ReadAllBytes(filePath); if (buf.Length == 0) { NIDebug.LogError(string.Format("读取{0}失败!", filePath)); continue; } versionItemInfo.Add(patchName, new List <object>() { newPatchVersion[patchName], 0, buf.Length }); File.Copy(filePath, string.Format("{0}{1}_{2}.zip", publishPath, patchName, newPatchVersion[patchName]), true); } // 有变化重新生成版本文件 if (isABChanged || isPatchChanged) { // 将资源版本添加到列表中 versionItemInfo.Add("res_version", new List <object>() { resVersion, 0, 0 }); // 生成某个目录下的版本控制文件 GenVersionFile(abPath, publishPath, versionItemInfo, abPatchDic); } // 标识Build AssetBundle OK NIDebug.Log("生成AssetBundle完成"); // 刷新编辑器 AssetDatabase.Refresh(); }