//filePath: D:/ TowerGame / Assets /../ Config / GameConfigGoto.json //fileName: GameConfigGoto private void DrawCreateBtn(string filePath, string fileName) { bool isNew = false; string buttonTxt = ""; string className = fileName.Replace("GameConfig", "") + "Config"; if (File.Exists(Application.dataPath + "/../" + CONFIG_FOLDER_NAME + "/" + className + ".cs")) { buttonTxt = "Update"; } else { buttonTxt = "Create"; isNew = true; } if (isNew) { GUI.color = Color.green; } if (GUILayout.Button(buttonTxt, GUILayout.Width(98f))) { NIEditorUtility.CreateCsConfigFile(filePath, fileName, CONFIG_FOLDER_NAME); } if (isNew) { GUI.color = Color.white; } }
/// <summary> /// Gens the patch files. /// </summary> /// <returns>The patch files.</returns> /// <param name="patchPatch">Patch patch.</param> /// <param name="versionItemSize">Version item size.</param> /// <param name="abPatchDic">Ab patch dic.</param> private static Dictionary <string, string> GenPatchFiles(string patchPath, string abPath, Dictionary <string, List <object> > versionItemInfo, ref Dictionary <string, string> abPatchDic) { Dictionary <string, string> patchVersionDic = new Dictionary <string, string>(); List <string> filterAB = new List <string>(); foreach (KeyValuePair <string, List <string> > item in AssetBundleNameTools.patchAbDict) { filterAB.Clear(); string md5Str = string.Empty; foreach (string reg in item.Value) { List <string> bundles = versionItemInfo.Keys.Where(bundle => (Regex.IsMatch(bundle, reg))).ToList <string>(); if (bundles.Count == 0) { NIDebug.LogError("生成patch时 {0} 筛选出来的文件个数为0,请检查!", reg); continue; } // 对文件按文件名称进行排序 bundles.Sort(delegate(string b1, string b2) { return(b1.CompareTo(b2)); }); foreach (string bundle in bundles) { filterAB.Add(string.Format("{0}{1}", abPath, bundle)); md5Str += versionItemInfo[bundle][0]; if (abPatchDic.ContainsKey(bundle)) { NIDebug.LogError(string.Format("{0}重复放在了{1}和{2}中,请检查!", bundle, abPatchDic[bundle], item.Key)); continue; } abPatchDic.Add(bundle, item.Key); } } string md5 = NIEditorUtility.GetStrMD5(md5Str); NIEditorUtility.Zip(filterAB.ToArray(), string.Format("{0}{1}_{2}.zip", patchPath, item.Key, md5)); patchVersionDic.Add(item.Key, md5); } return(patchVersionDic); }
/// <summary> /// 收集新资源版本信息 /// </summary> private static Dictionary <string, string> DoCollectNewABVersion(string abPath, AssetBundleManifest manifest) { // 版本信息 Dictionary <string, string> versionDict = new Dictionary <string, string>(); // 收集新变化的ab // 将主AssetBundle也加入到version中 string md5 = NIEditorUtility.GetFileMD5(string.Format("{0}/{1}", abPath, MAIN_ASSET_BUNDLE_NAME)); versionDict.Add(MAIN_ASSET_BUNDLE_NAME, md5); // 遍历该文件下的所有AssetBundles foreach (string abName in manifest.GetAllAssetBundles()) { md5 = NIEditorUtility.GetFileMD5(string.Format("{0}/{1}", abPath, abName)); // 记录版本信息 versionDict.Add(abName, md5); } // 返回新生成的版本信息 return(versionDict); }
private void OnGUI() { GUILayout.BeginVertical(); // 绘制作者信息 NIEditorUtility.DrawAuthorSummary(); GUILayout.Space(5); if (GUILayout.Button("刷新", GUILayout.MaxWidth(70))) { Refresh(); return; } GUILayout.Space(5); GUILayout.EndVertical(); GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUI.backgroundColor = new Color32(150, 200, 255, 255); //未创建的在前,已创建的在后 dirList.Sort((string a, string b) => { string aPath = a.Replace("Z_RES/Atlas/", "Assets/Art/Atlas/"); string bPath = b.Replace("Z_RES/Atlas/", "Assets/Art/Atlas/"); bool ae = Directory.Exists(aPath); bool be = Directory.Exists(bPath); if (ae && !be) { return(1); } else if (!ae && be) { return(-1); } else { //GetFileNameWithoutExtension得到没有扩充名(.txt)的文件名 //按首字母排序 string aN = Path.GetFileNameWithoutExtension(a); string bN = Path.GetFileNameWithoutExtension(b); return(aN[0] - bN[0]); } }); //文件夹列表 scrollPos = GUILayout.BeginScrollView(scrollPos, "AS TextArea", GUILayout.Width(480), GUILayout.Height(600)); for (int i = 0; i < dirList.Count; i++) { string atlasName = Path.GetFileNameWithoutExtension(dirList[i]); GUILayout.BeginHorizontal(); GUILayout.Space(10f); string resPath = dirList[i].Replace("Z_RES/Atlas/", "Assets/Art/Atlas/"); string buttonTxt = ""; bool isNew = false; if (Directory.Exists(resPath)) { buttonTxt = "更新"; } else { buttonTxt = "创建"; isNew = true; } if (isNew) { GUI.color = Color.green; } //1.创建/更新按钮 if (GUILayout.Button(buttonTxt, GUILayout.Width(50), GUILayout.Height(20))) { MakeAtlas(atlasName); } if (isNew) { GUI.color = Color.white; } //2.文件夹名 GUILayout.Label(atlasName, EditorStyles.boldLabel); //3.配置文件按钮 if (!isNew) { if (GUILayout.Button("配置", GUILayout.Width(70f), GUILayout.Height(20))) { if (File.Exists(ATLAS_PREFAB_PATH + atlasName + "Atlas" + ".prefab")) { UIAtlas atlas = Resources.Load <UIAtlas>("Atlas/" + atlasName + "Atlas"); string textPath = ATLAS_PATH + atlasName + ".txt"; textPath = GetProjectRelativePath(textPath); TextAsset configuration = AssetDatabase.LoadAssetAtPath <TextAsset>(textPath); NGUIJson.LoadSpriteData(atlas, configuration); //装载图集配置文件 atlas.MarkAsChanged(); PrefabUtility.RecordPrefabInstancePropertyModifications(atlas); } } } GUILayout.EndHorizontal(); GUILayout.Space(10f); } GUILayout.EndScrollView(); GUI.backgroundColor = Color.white; GUILayout.Space(10f); GUILayout.EndVertical(); GUILayout.EndHorizontal(); }
private void OnGUI() { //头像 GUILayout.Space(10); NIEditorUtility.DrawAuthorSummary(); GUILayout.Space(10); //选择目标目录 GUILayout.Space(10); GUILayout.BeginHorizontal(); { GUILayout.Space(5); GUIStyle style = EditorStyles.textArea; style.fontStyle = FontStyle.Bold; style.alignment = TextAnchor.MiddleLeft; GUILayout.Label(FILE_ROOT_PATH, style, GUILayout.Height(25)); if (GUILayout.Button("SetPath", GUILayout.MaxWidth(65f))) { string tempPath = NIEditorUtility.BrowseFolder(); if (!string.IsNullOrEmpty(tempPath)) { FILE_ROOT_PATH = tempPath; Refresh(); } return; } if (GUILayout.Button("ResetPath", GUILayout.MaxWidth(75f))) { FILE_ROOT_PATH = Application.dataPath + "/../" + CONFIG_JSON_FOLER_NAME; Refresh(); return; } } GUILayout.EndHorizontal(); GUILayout.Space(10); //内容 GUI.backgroundColor = new Color32(150, 200, 255, 255); GUILayout.BeginVertical("AS TextArea", GUILayout.Height(500)); { GUILayout.BeginHorizontal(); GUILayout.Label("Config File Name", EditorStyles.toolbarButton); GUILayout.Label("Operation", EditorStyles.toolbarButton); GUILayout.EndHorizontal(); _scrollPos = GUILayout.BeginScrollView(_scrollPos, GUILayout.Height(470)); for (int i = 0; i < mFilesPathList.Count; i++) { string fileName = Path.GetFileNameWithoutExtension(mFilesPathList[i]); GUILayout.BeginHorizontal(); { GUIStyle style = EditorStyles.textArea; style.fontStyle = FontStyle.Bold; style.alignment = TextAnchor.MiddleLeft; GUILayout.Label(fileName, style, GUILayout.Height(25)); DrawCreateBtn(mFilesPathList[i], fileName); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } GUILayout.EndVertical(); //刷新 GUILayout.Space(10f); GUILayout.BeginHorizontal(); { GUILayout.Space(10); if (GUILayout.Button("Refresh", GUILayout.MaxWidth(60f))) { Refresh(); return; } GUILayout.Space(2); GUILayout.Label("To refresh Config Files"); } GUILayout.EndHorizontal(); //创建全部 GUILayout.Space(10); GUILayout.BeginHorizontal(); { GUILayout.Space(10); if (GUILayout.Button("Create All", GUILayout.MaxWidth(80f))) { for (int i = 0; i < mFilesPathList.Count; i++) { string fileName = Path.GetFileNameWithoutExtension(mFilesPathList[i]); NIEditorUtility.CreateCsConfigFile(mFilesPathList[i], fileName, CONFIG_FOLDER_NAME); } return; } GUILayout.Space(2); GUILayout.Label("To Create All Config Files"); } GUILayout.EndHorizontal(); //生成到目标路径 GUILayout.BeginVertical(); { GUILayout.Space(10); GUILayout.Label("生成到目标路径:"); GUI.color = Color.white; GUIStyle style = EditorStyles.textArea; style.fontStyle = FontStyle.Bold; style.alignment = TextAnchor.MiddleLeft; GUILayout.Label(Application.dataPath + "/../" + CONFIG_FOLDER_NAME, style, GUILayout.Height(25)); } GUILayout.EndVertical(); }
/// <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(); }