using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.Reflection; using System.Security.Cryptography; using System.Text; using UnityEditor; using UnityEditor.U2D; using UnityEngine; using UnityEngine.U2D; using UnityEngine.UI.PackgTool; using Debug = UnityEngine.Debug; using Object = System.Object; namespace UnityEditor.UI { public class UGUIPackgToolWindow : EditorWindow { public class SVNInfo { public int yb; public int bb; public string url; } private Vector2 pos = Vector2.zero; private static string dbPath; public string findName; private static string packgPath; int bbh1 = 0; int bbh2 = 0; [UnityEditor.MenuItem("UI/图集")] public static void Open() { packgPath = Application.dataPath.Replace("Assets", "UGUIPack/"); if (!System.IO.Directory.Exists(packgPath)) { Directory.CreateDirectory(packgPath); } dbPath = packgPath + "uguiconfig.db"; UGUIPackgToolWindow uguiPackgToolWindow = UGUIPackgToolWindow.GetWindow(); uguiPackgToolWindow.Show(); } public void SetSVNInfo() { SVNInfo svnInfo = BanBenXinXing($"info {UGUICacheInfo.uguiPackDB.uiPath2}"); if (!string.IsNullOrEmpty(svnInfo.url)) { SVNInfo svnInfo2 = BanBenXinXing($"info {svnInfo.url}"); bbh1 = svnInfo2.bb; bbh2 = svnInfo.bb; } } public SVNInfo BanBenXinXing(string par) { if (!string.IsNullOrEmpty(UGUICacheInfo.uguiPackDB.uiPath2)) { SVNInfo svnInfo = new SVNInfo(); List info = Proce(par); if (info.Count <= 0) { return svnInfo; } for (int i = 0; i < info.Count; i++) { int index = info[i].IndexOf(":"); if (index <= 0) { continue; } string key = info[i].Substring(0, index); string value = info[i].Substring(index + 1); if (key.Equals("Revision")) { string v1 = value.Replace(" ", ""); svnInfo.yb = int.Parse(v1); } if (key.Equals("Last Changed Rev")) { string v1 = value.Replace(" ", ""); svnInfo.bb = int.Parse(v1); } if (key.Equals("URL")) { svnInfo.url = value; } } return svnInfo; } return null; } private void OnEnable() { SetSVNInfo(); } private List Proce(string par) { string allPath = UGUICacheInfo.uguiPackDB.uiPath2.Replace("unity_use_ui/", "工具/bin/svn.exe"); ProcessStartInfo processStartInfo = new System.Diagnostics.ProcessStartInfo(allPath, par); processStartInfo.CreateNoWindow = true; processStartInfo.UseShellExecute = false; processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardError = true; System.Diagnostics.Process process = new Process(); process.StartInfo = processStartInfo; process.Start(); process.WaitForExit(); while (!process.StandardError.EndOfStream) { return new List(); } List allInfo = new List(); while (!process.StandardOutput.EndOfStream) { allInfo.Add(process.StandardOutput.ReadLine()); } process.Close(); return allInfo; } private void OnGUI() { if (dbPath == null) { Open(); } if (UGUICacheInfo.uguiPackDB == null) { return; } GUILayout.BeginHorizontal(); Color color = GUI.color; if (bbh1 != 0 && bbh1 != bbh2) { GUI.color = Color.red; if (GUILayout.Button("SVN有新的内容,请更新SVN")) { } } else { } GUI.color = color; GUILayout.Label($"远程版本号{bbh1}___本地版本号{bbh2}"); GUILayout.EndHorizontal(); if (GUILayout.Button("清空缓存")) { PlayerPrefs.SetString("uiPath", ""); UGUICacheInfo.Clare(); } if (string.IsNullOrEmpty(UGUICacheInfo.uguiPackDB.uiPath2)) { if (GUILayout.Button("选在服务器UI")) { string path = EditorUtility.OpenFolderPanel("选择来源文件夹", "", "") + "/"; if (!File.Exists(path + "art.config")) { EditorUtility.DisplayDialog("错误提示", "选择的文件夹错误,没有找到对应的美术配置", "确定"); } else { PlayerPrefs.SetString("uiPath", path); UGUICacheInfo.uguiPackDB.uiPath2 = path; SetSVNInfo(); } } return; } else if (!UGUICacheInfo.uguiPackDB.isJiaoYan) { if (!File.Exists(UGUICacheInfo.uguiPackDB.uiPath2 + "art.config")) { EditorUtility.DisplayDialog("错误提示", "选择的文件夹错误,没有找到对应的美术配置", "确定"); UGUICacheInfo.uguiPackDB.uiPath2 = null; return; } else { UGUICacheInfo.uguiPackDB.isJiaoYan = true; } } { if (GUILayout.Button("更新服务器UI到unity")) { UpdateArt(); } } if (!UGUICacheInfo.uguiPackDB.isShowPack && GUILayout.Button("显示图集")) { UGUICacheInfo.AllTextrueJsons.Clear(); string targetFilePath = Application.dataPath + "/Art/UIAssets/TextrueJson"; if (!Directory.Exists(targetFilePath)) { return; } UGUICacheInfo.uguiPackDB.ClearUselessPack(); string[] allFile = System.IO.Directory.GetFiles(targetFilePath, "*.txt"); //当前所有的图集 for (int i = 0; i < allFile.Length; i++) { TextrueJson textrueJson = JsonUtility.FromJson(File.ReadAllText(allFile[i])); UGUICacheInfo.AllTextrueJsons.Add(textrueJson); PackInfo packInfo = UGUICacheInfo.uguiPackDB.GetPackgInfo(textrueJson.packName); string currGuid = GetFileMD5(allFile[i]); if (packInfo == null) { packInfo = UGUICacheInfo.AddNewPackInfo(allFile[i].Replace(Application.dataPath, ""), textrueJson); } else if (!string.IsNullOrEmpty(packInfo.packgJsonPath)) { if (!File.Exists(Application.dataPath + packInfo.packgJsonPath)) { packInfo.packgJsonPath = allFile[i].Replace(Application.dataPath, ""); } } if (string.IsNullOrEmpty(packInfo.lasetJsonGUID) || !currGuid.Equals(packInfo.lasetJsonGUID)) { packInfo.isUpdate = true; } } UGUICacheInfo.uguiPackDB.isShowPack = true; string json = JsonUtility.ToJson(UGUICacheInfo.uguiPackDB); File.WriteAllText(dbPath, json); } if (UGUICacheInfo.uguiPackDB.isShowPack && GUILayout.Button("隐藏图集")) { UGUICacheInfo.uguiPackDB.isShowPack = false; } if (UGUICacheInfo.uguiPackDB.isShowPack) { ShowPack(); } } private void ShowPack() { GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("筛查"); findName = UnityEditor.EditorGUILayout.TextArea(findName); if (GUILayout.Button("一键")) { try { for (int j = 0; j < UGUICacheInfo.uguiPackDB.allPackgInfos.Count; j++) { PackInfo packInfo = UGUICacheInfo.uguiPackDB.allPackgInfos[j]; SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath(packInfo.packgSpritePath); if (spriteAtlas == null) { continue; } string json = File.ReadAllText(Application.dataPath + packInfo.packgJsonPath); TextrueJson textrueJson = JsonUtility.FromJson(json); List allAddAsset = new List(); UnityEngine.Object[] currObject = spriteAtlas.GetPackables(); spriteAtlas.Remove(currObject); for (int i = 0; i < textrueJson.newTextureJson.Count; i++) { if (textrueJson.newTextureJson[i].textrueName.Contains("bg_")) { continue; } if (string.IsNullOrEmpty(textrueJson.newTextureJson[i].textrueName)) { continue; } TextrueJson tongYong = UGUICacheInfo.GetTongYong(textrueJson.newTextureJson[i].textrueName); if (tongYong != null && !tongYong.packName.Equals(packInfo.packName)) { continue; } // string[] guidUI = AssetDatabase.FindAssets(textrueName); string textrueName = textrueJson.newTextureJson[i].textrueName; string[] guidUI = AssetDatabase.FindAssets(textrueName); if (guidUI != null && guidUI.Length > 0) { for (int k = 0; k < guidUI.Length; k++) { string path = AssetDatabase.GUIDToAssetPath(guidUI[k]); if (!path.Contains(".png")) { continue; } UnityEngine.Object obj = AssetDatabase.LoadMainAssetAtPath(path); TextureImporter emojiTex = AssetImporter.GetAtPath(path) as TextureImporter; if (emojiTex != null && emojiTex.textureType != TextureImporterType.Sprite) { emojiTex.textureType = TextureImporterType.Sprite; emojiTex.SaveAndReimport(); } if (!obj.name.Equals(textrueName)) { continue; } allAddAsset.Add(obj); break; } // string path = AssetDatabase.GUIDToAssetPath(guidUI[0]); // if (!path.Contains(".png")) // { // continue; // } // // UnityEngine.Object obj = AssetDatabase.LoadMainAssetAtPath(path); // TextureImporter emojiTex = AssetImporter.GetAtPath(path) as TextureImporter; // if (emojiTex != null && emojiTex.textureType != TextureImporterType.Sprite) // { // emojiTex.textureType = TextureImporterType.Sprite; // emojiTex.SaveAndReimport(); // } // // allAddAsset.Add(obj); } } spriteAtlas.SetIncludeInBuild(false); SpriteAtlasExtensions.Add(spriteAtlas, allAddAsset.ToArray()); EditorUtility.SetDirty(spriteAtlas); SpriteAtlasUtility.PackAtlases(new SpriteAtlas[] { spriteAtlas }, BuildTarget.Android); packInfo.lasetJsonGUID = GetFileMD5(Application.dataPath + packInfo.packgJsonPath); packInfo.isUpdate = false; string dbjson = JsonUtility.ToJson(UGUICacheInfo.uguiPackDB); File.WriteAllText(dbPath, dbjson); } // UGUIGameObjectTool.ReviewUI(UGUICacheInfo.atlasList, spriteAtlas, packInfo); } catch (Exception e) { Debug.LogError(e); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } GUILayout.EndHorizontal(); int maxHeight = UGUICacheInfo.uguiPackDB.allPackgInfos.Count * (356) + 1000; pos = GUI.BeginScrollView( new Rect(0, 100, EditorGUIUtility.currentViewWidth, this.position.height), pos, new Rect(0, 0, 10000, maxHeight), false, true); Rect rect = new Rect(0, 70, 0, 0); for (int i = 0; i < UGUICacheInfo.uguiPackDB.allPackgInfos.Count; i++) { PackInfo packInfo = UGUICacheInfo.uguiPackDB.allPackgInfos[i]; if (!string.IsNullOrEmpty(findName) && !packInfo.packName.Contains(findName)) { continue; } // if ((!packInfo.isUpdate || string.IsNullOrEmpty(packInfo.packgSpritePath))) // { // continue; // } DrawPack(packInfo, rect); rect.y += 256 + 100; } GUI.EndScrollView(); } private void DrawPack(PackInfo packInfo, Rect rect) { GUI.Box(new Rect(0, rect.y - 20, EditorGUIUtility.currentViewWidth - 180, 300), ""); GUILayout.BeginHorizontal(); float x = 30; GUI.Label(new Rect(x, rect.y + 10, 200, 30), packInfo.packName); x += 200; if (packInfo.isPackError) { x += 50; if (GUI.Button(new Rect(x, rect.y, 50, 30), "校验" + packInfo.packName)) { packInfo.isPackError = false; } } x += 50; Rect buttonRect = new Rect(x, rect.y, 50, 50); if (GUI.Button(buttonRect, "更新")) { SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath(packInfo.packgSpritePath); if (spriteAtlas == null) { return; } string json = File.ReadAllText(Application.dataPath + packInfo.packgJsonPath); TextrueJson textrueJson = JsonUtility.FromJson(json); List allAddAsset = new List(); UnityEngine.Object[] currObject = spriteAtlas.GetPackables(); SpriteAtlasExtensions.Remove(spriteAtlas, currObject); spriteAtlas.Remove(currObject); // spriteAtl = 0; for (int i = 0; i < textrueJson.newTextureJson.Count; i++) { string textrueName = textrueJson.newTextureJson[i].textrueName; if (textrueName.Contains("bg_")) { continue; } if (string.IsNullOrEmpty(textrueName)) { continue; } TextrueJson tongYong = UGUICacheInfo.GetTongYong(textrueName); if (tongYong != null && !tongYong.packName.Equals(packInfo.packName)) { continue; } string[] guidUI = AssetDatabase.FindAssets(textrueName); if (guidUI != null && guidUI.Length > 0) { for (int j = 0; j < guidUI.Length; j++) { string path = AssetDatabase.GUIDToAssetPath(guidUI[j]); if (!path.Contains(".png")) { continue; } UnityEngine.Object obj = AssetDatabase.LoadMainAssetAtPath(path); TextureImporter emojiTex = AssetImporter.GetAtPath(path) as TextureImporter; if (emojiTex != null && emojiTex.textureType != TextureImporterType.Sprite) { emojiTex.textureType = TextureImporterType.Sprite; emojiTex.SaveAndReimport(); } if (!obj.name.Equals(textrueName)) { continue; } allAddAsset.Add(obj); break; } } } spriteAtlas.SetIncludeInBuild(false); SpriteAtlasAsset spriteAtlasAsset = SpriteAtlasAsset.Load(packInfo.packgSpritePath); MethodInfo methodInfo = spriteAtlasAsset.GetType() .GetMethod("RemoveAt", BindingFlags.Instance | BindingFlags.NonPublic); for (int i = 0; i < spriteAtlas.spriteCount * 3; i++) { methodInfo.Invoke(spriteAtlasAsset, new object[] { 0 }); } // spriteAtlasAsset.Remove(sprites); spriteAtlasAsset.Add(allAddAsset.ToArray()); SpriteAtlasAsset.Save(spriteAtlasAsset, packInfo.packgSpritePath); // spriteAtlasAsset. EditorUtility.SetDirty(spriteAtlas); AssetDatabase.SaveAssets(); SpriteAtlasUtility.PackAtlases(new SpriteAtlas[] { spriteAtlas }, BuildTarget.NoTarget); AssetDatabase.Refresh(); packInfo.lasetJsonGUID = GetFileMD5(Application.dataPath + packInfo.packgJsonPath); packInfo.isUpdate = false; string dbjson = JsonUtility.ToJson(UGUICacheInfo.uguiPackDB); File.WriteAllText(dbPath, dbjson); UGUIGameObjectTool.ReviewUI(UGUICacheInfo.atlasList, spriteAtlas, packInfo); } if (string.IsNullOrEmpty(packInfo.packgSpritePath) || packInfo.spriteAtlas == null) { x += 50; buttonRect = new Rect(x, rect.y, 50, 50); if (GUI.Button(buttonRect, "创建")) { string path = "Assets/Res/UIAtlas/"; // string defaultPath = path + "default.spriteatlas"; string assetPath = Application.dataPath.Replace("Assets", "") + path + packInfo.packName + ".spriteatlasv2"; if (!File.Exists(assetPath)) { string n = path + "MoBan.spriteatlasv2"; string newP = path + packInfo.packName + ".spriteatlasv2"; AssetDatabase.CopyAsset(n, newP); // SpriteAtlas spriteAtlas = new SpriteAtlas(); // AssetDatabase.CreateAsset(spriteAtlas, path + packInfo.packName + ".spriteatlasv2"); AssetDatabase.ImportAsset(path + packInfo.packName + ".spriteatlasv2"); AssetDatabase.SaveAssets(); SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath(newP); UGUICacheInfo.atlasList.Add(spriteAtlas); packInfo.spriteAtlas = spriteAtlas; // AssetDatabase.Refresh(); // File.Copy(Application.dataPath.Replace("Assets", "") + defaultPath, assetPath); // AssetDatabase.Refresh(); // AssetDatabase.SaveAssets(); } packInfo.isUpdate = true; packInfo.packgSpritePath = path + packInfo.packName + ".spriteatlasv2"; string json = JsonUtility.ToJson(UGUICacheInfo.uguiPackDB); File.WriteAllText(dbPath, json); } } x += 50; Rect shuaXing = new Rect(x, rect.y, 50, 50); if (GUI.Button(shuaXing, "刷新")) { SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath(packInfo.packgSpritePath); if (spriteAtlas != null) { UGUIGameObjectTool.ReviewUI(UGUICacheInfo.atlasList, spriteAtlas, packInfo); } } if (packInfo.packName != null && packInfo.spriteAtlas == null && packInfo.isPackError == false) { packInfo.spriteAtlas = UGUICacheInfo.GetSpriteAtlas(packInfo.packName); if (packInfo.spriteAtlas == null) { packInfo.lasetJsonGUID = null; packInfo.isPackError = true; } else { packInfo.packgSpritePath = AssetDatabase.GetAssetPath(packInfo.spriteAtlas); } UGUICacheInfo.SaveDB(); } if (packInfo.spriteAtlas != null) { x += 50; EditorGUI.ObjectField(new Rect(x, rect.y, 150, 50), packInfo.spriteAtlas, typeof(SpriteAtlas)); x += 150; if (GUI.Button(new Rect(x, rect.y, 50, 50), "删除")) { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(packInfo.spriteAtlas)); packInfo.spriteAtlas = null; AssetDatabase.Refresh(); } } GUILayout.EndHorizontal(); // rect.y += 50; // if (packInfo.spriteAtlas != null) // { // Rect scrolViewRect = new Rect(0, rect.y, EditorGUIUtility.currentViewWidth - 200, 256); // MethodInfo getPreviewTextures = packInfo.spriteAtlas.GetType() // .GetMethod("GetPreviewTextures"); // Texture2D[] allTack = (Texture2D[])getPreviewTextures.Invoke(packInfo.spriteAtlas, null); // // Texture2D[] allTack = packInfo.spriteAtlas.GetPreviewTextures(); // packInfo.movePos = GUI.BeginScrollView(scrolViewRect, packInfo.movePos, // new Rect(0, 0, allTack.Length * 356, 250), false, false); // // // Rect textrueRect = new Rect(30, 0, 256, 256); // for (int i = 0; i < allTack.Length; i++) // { // GUI.DrawTexture(textrueRect, allTack[i], ScaleMode.ScaleToFit); // textrueRect.x += 256 + 100; // } // // GUI.EndScrollView(); // } } private void UpdateArt() { string[] scorPath = Directory.GetFiles(UGUICacheInfo.uguiPackDB.uiPath2, "*", SearchOption.AllDirectories); string[] targetPath = Directory.GetFiles(Application.dataPath + "/Art/UIAssets", "*", SearchOption.AllDirectories); //更新资源 UpdateFile(scorPath); DelectFile(targetPath); } private void DelectFile(string[] targetPath) { for (int i = 0; i < targetPath.Length; i++) { string filePath = targetPath[i].Replace("\\", "/"); filePath = UGUICacheInfo.uguiPackDB.uiPath2 + filePath.Replace(Application.dataPath + "/Art/UIAssets/", ""); if (filePath.Contains(".meta") || filePath.Contains("TextureSettingConfig") || filePath.Contains("dbdata") || filePath.Contains("art.config")) { continue; } if (!File.Exists(filePath)) { File.Delete(targetPath[i]); } } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } private void UpdateFile(string[] scorPath) { for (int i = 0; i < scorPath.Length; i++) { if (scorPath[i].Contains(".svn")) { continue; } string filePath = scorPath[i].Replace(UGUICacheInfo.uguiPackDB.uiPath2, ""); string scorFilePath = scorPath[i]; string targetFilePath = Application.dataPath + "/Art/UIAssets/" + filePath; string dirPath = targetFilePath.Replace(Path.GetFileName(scorFilePath), ""); if (!System.IO.Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } if (File.Exists(targetFilePath)) //替换 { string sucMd5 = GetFileMD5(scorFilePath); string taggetMd5 = GetFileMD5(targetFilePath); if (!sucMd5.Equals(taggetMd5)) //图片变化 { string fileName = Path.GetFileNameWithoutExtension(scorFilePath); File.Copy(scorFilePath, targetFilePath, true); AssetDatabase.ImportAsset(targetFilePath.Replace(Application.dataPath, "Assets"), ImportAssetOptions.ForceUpdate); TextureImporter emojiTex = AssetImporter.GetAtPath(targetFilePath.Replace(Application.dataPath, "Assets")) as TextureImporter; if (emojiTex != null) { emojiTex.textureType = TextureImporterType.Sprite; emojiTex.SaveAndReimport(); } } } else //新加 { try { if (!scorFilePath.Contains("效果图")) { // AssetDatabase.ImportAsset(scorFilePath); File.Copy(scorFilePath, targetFilePath, true); AssetDatabase.ImportAsset(targetFilePath.Replace(Application.dataPath, "Assets"), ImportAssetOptions.ForceUpdate); TextureImporter emojiTex = AssetImporter.GetAtPath(targetFilePath.Replace(Application.dataPath, "Assets")) as TextureImporter; if (emojiTex != null) { emojiTex.textureType = TextureImporterType.Sprite; emojiTex.SaveAndReimport(); } } } catch (System.Exception e) { Debug.LogError(e); } } //string } string[] jsonPath = Directory.GetFiles(UGUICacheInfo.uguiPackDB.uiPath2 + "TextrueJson", "*.txt", SearchOption.AllDirectories); for (int i = 0; i < jsonPath.Length; i++) { string filePath = jsonPath[i].Replace(UGUICacheInfo.uguiPackDB.uiPath2, ""); string scorFilePath = jsonPath[i]; string targetFilePath = Application.dataPath + "/Art/UIAssets/" + filePath; File.Copy(scorFilePath, targetFilePath, true); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } private string GetFileMD5(string filePath) { FileStream file = new FileStream(filePath, System.IO.FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); file.Close(); file.Dispose(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } } }