From afd53f6b3c0583e74c783c7c0653aa7d0588b1b9 Mon Sep 17 00:00:00 2001 From: client_Wu Xijin <364452445@qq.com> Date: 星期二, 16 四月 2019 14:54:19 +0800 Subject: [PATCH] 6519 【工具】【2.0】删除无用KYE的工具 --- Assets/Editor/Tool/EffectAssetCheck.cs.meta | 12 + Assets/Editor/Tool/UIAssetCheck.cs | 17 + Assets/Editor/Tool/EffectAssetCheck.cs | 659 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 688 insertions(+), 0 deletions(-) diff --git a/Assets/Editor/Tool/EffectAssetCheck.cs b/Assets/Editor/Tool/EffectAssetCheck.cs new file mode 100644 index 0000000..b2e4811 --- /dev/null +++ b/Assets/Editor/Tool/EffectAssetCheck.cs @@ -0,0 +1,659 @@ +锘�//------------------------------------------------------------------ +//鏈枃浠朵腑鐨勫伐鍏锋彁渚涘湪缂栬緫鍣ㄧ幆澧冧笅锛屽揩閫熸暣鐞嗙壒鏁堢浉鍏崇殑璧勬簮 +//------------------------------------------------------------------- + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using UnityEngine.UI; +using System.IO; +using System; +using System.Threading; +using System.Text.RegularExpressions; + +public class RemoveUnUsedEffect +{ + static string uiroot1 = "Assets/ResourcesOut/UI/Window"; + static string uiroot2 = "Assets/ResourcesOut/UI/PriorityWindow"; + static string uiroot3 = "Assets/ResourcesOut/UI/Prefab"; + static string mobroot = "Assets/ResourcesOut/UI/Prefab"; + static string builtinroot = "Assets/ResourcesOut/BuiltIn/Prefabs"; + + static string effectroot = "Assets/ResourcesOut/Effect"; + + static List<string> prefabTexts = new List<string>(); + + static Dictionary<string, GameObject> processObjects = new Dictionary<string, GameObject>(); + static List<AnalyzeTask> tasks = new List<AnalyzeTask>(); + + static int taskCount = 1; + static int completedTaskCount = 0; + static List<EffectConfig> configs; + + [MenuItem("绋嬪簭/Effect Assets/绉婚櫎鏃犵敤鐨勭壒鏁�")] + public static void RemoveUnUsedEffects() + { + try + { + EditorApplication.update += OnUpdate; + EffectConfig.Init(true); + configs = EffectConfig.GetValues(); + + LoadPrefabTexts(); + FindEffects(); + + taskCount = 0; + completedTaskCount = 0; + foreach (var task in tasks) + { + task.total = task.effects.Count; + taskCount += task.total; + } + + Analyze(); + } + catch (Exception e) + { + EditorApplication.update -= OnUpdate; + EditorUtility.ClearProgressBar(); + } + } + + static void LoadPrefabTexts() + { + var guids = new List<string>(); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot1 })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot2 })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot3 })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { mobroot })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { builtinroot })); + + var assetPaths = new List<string>(); + foreach (var item in guids) + { + assetPaths.Add(AssetDatabase.GUIDToAssetPath(item)); + } + + var count = 0; + prefabTexts.Clear(); + foreach (var path in assetPaths) + { + count++; + EditorUtility.DisplayProgressBar("璇诲彇棰勭疆浣�", "姝e湪璇诲彇棰勭疆浣撴枃鏈�", (float)count / assetPaths.Count); + prefabTexts.Add(File.ReadAllText(Application.dataPath + path.Substring(6, path.Length - 6))); + } + + EditorUtility.ClearProgressBar(); + } + + static void FindEffects() + { + processObjects.Clear(); + tasks.Clear(); + + var effects = new List<GameObject>(); + var guids = new List<string>(); + var subFolders = AssetDatabase.GetSubFolders(effectroot); + foreach (var folder in subFolders) + { + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { folder })); + } + + foreach (var guid in guids) + { + effects.Add(AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(guid))); + } + + var count = 0; + var task = new AnalyzeTask(); + tasks.Add(task); + foreach (var asset in effects) + { + var path = AssetDatabase.GetAssetPath(asset); + var guid = AssetDatabase.AssetPathToGUID(path); + processObjects[guid] = asset; + + var folderName = Path.GetDirectoryName(path).Split('/').GetLast(); + task.Add(new EffectInfo() + { + name = asset.name, + guid = guid, + folder = folderName + }); + + count++; + EditorUtility.DisplayProgressBar("鑾峰彇鐗规晥", "姝e湪鑾峰彇鐗规晥棰勭疆浣�", (float)count / effects.Count); + if (count >= 20) + { + count = 0; + task = new AnalyzeTask(); + tasks.Add(task); + } + } + + EditorUtility.ClearProgressBar(); + + } + + static void Analyze() + { + foreach (var task in tasks) + { + ThreadPool.QueueUserWorkItem(x => + { + for (int i = 0; i < task.effects.Count; i++) + { + task.completed++; + var info = task.effects[i]; + if (ContainByIconTable(info)) + { + continue; + } + + if (RefrenceByPrefab(info)) + { + continue; + } + + info.unUsed = true; + task.effects[i] = info; + } + + task.done = true; + }); + } + } + + static void ProcessUnUsedEffects() + { + var total = 0; + foreach (var task in tasks) + { + foreach (var effect in task.effects) + { + if (effect.unUsed) + { + Debug.LogFormat("鎵惧埌涓�涓棤鐢ㄧ殑Effect锛氭枃浠跺す->{0};鐗规晥鍚嶇О->{1}", effect.folder, effect.name); + total++; + } + } + } + + var count = 0; + foreach (var task in tasks) + { + foreach (var sprite in task.effects) + { + if (sprite.unUsed) + { + EditorUtility.DisplayProgressBar("鍒犻櫎Effect", string.Format("姝e湪鍒犻櫎绗瑊0}涓壒鏁堬紝鍏眥1}涓�", count + 1, total), (float)count / total); + count++; + AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(sprite.guid)); + } + } + } + + EditorUtility.ClearProgressBar(); + } + + static bool ContainByIconTable(EffectInfo info) + { + return configs.FindIndex(x => { return x.packageName.ToLower() == info.folder.ToLower() && x.fxName == info.name; }) != -1; + } + + static bool RefrenceByPrefab(EffectInfo info) + { + foreach (var content in prefabTexts) + { + if (Regex.IsMatch(content, info.guid)) + { + return true; + } + } + + return false; + } + + static void OnUpdate() + { + var done = true; + completedTaskCount = 0; + foreach (var task in tasks) + { + completedTaskCount += task.completed; + if (!task.done) + { + done = false; + } + } + + EditorUtility.DisplayProgressBar("鍒嗘瀽鏃犵敤Effect", + string.Format("姝e湪鍒嗘瀽绗瑊0}涓狤ffect,鍏辫{1}涓�", completedTaskCount + 1, taskCount), + (float)completedTaskCount / taskCount); + + if (done) + { + EditorUtility.ClearProgressBar(); + ProcessUnUsedEffects(); + EditorApplication.update -= OnUpdate; + } + } + + struct EffectInfo + { + public string guid; + public string name; + public string folder; + public bool unUsed; + } + + class AnalyzeTask + { + public int total; + public int completed; + public bool done; + public List<EffectInfo> effects; + + public AnalyzeTask() + { + effects = new List<EffectInfo>(); + } + + public void Add(EffectInfo info) + { + effects.Add(info); + } + } + +} + +public class RemoveUnUsedEffectKey +{ + static string uiroot1 = "Assets/ResourcesOut/UI/Window"; + static string uiroot2 = "Assets/ResourcesOut/UI/PriorityWindow"; + static string uiroot3 = "Assets/ResourcesOut/UI/Prefab"; + + static int taskCount = 1; + static int completedTaskCount = 0; + static Dictionary<string, List<string>> iconKeyMap = new Dictionary<string, List<string>>(); + + static List<UIEffect> uieffects = new List<UIEffect>(); + static List<Column> iconKeyRefrences = new List<Column>(); + static List<string> csharpFileContents = new List<string>(); + static List<AnalyzeTask> tasks = new List<AnalyzeTask>(); + + [MenuItem("绋嬪簭/Effect Assets/绉婚櫎鏃犵敤鐨凟ffectKey")] + public static void Remove() + { + tasks.Clear(); + var effectKeys = GetOriginalEffectKeys(); + + taskCount = effectKeys.Count; + completedTaskCount = 0; + + var count = 0; + var task = new AnalyzeTask(); + tasks.Add(task); + foreach (var keyInfo in effectKeys) + { + task.Add(keyInfo); + if (count >= 100) + { + count = 0; + task = new AnalyzeTask(); + tasks.Add(task); + } + count++; + } + + iconKeyMap = GetEffectKeyMap(); + iconKeyRefrences = GetAllEffectKeyRefrences(); + csharpFileContents = GetAllCSharpFileContents(); + uieffects = GetEffectComponents(); + + try + { + EditorApplication.update += OnUpdate; + Analyze(); + } + catch (Exception e) + { + EditorUtility.ClearProgressBar(); + EditorApplication.update -= OnUpdate; + Debug.Log(e); + } + + } + + static void Analyze() + { + foreach (var task in tasks) + { + ThreadPool.QueueUserWorkItem(x => + { + for (int i = 0; i < task.effectKeys.Count; i++) + { + task.completed++; + var info = task.effectKeys[i]; + if (info.folder.ToLower() == "cj") + { + continue; + } + + if (ContainByTables(info.key, ref iconKeyRefrences)) + { + Debug.LogFormat("鎵惧埌涓�涓鍏朵粬閰嶇疆閰嶄欢寮曠敤鐨� effect key锛歿0}", info.key); + continue; + } + + if (ContainByCSharpFile(info.key, ref csharpFileContents)) + { + Debug.LogFormat("鎵惧埌涓�涓啓鍦–#鏂囦欢涓殑 effect key锛歿0}", info.key); + continue; + } + + if (ContainByPrefab(info.key, ref uieffects)) + { + Debug.LogFormat("鎵惧埌涓�涓prefab渚濊禆鐨� effect key锛歿0}", info.key); + continue; + } + + info.unused = true; + task.effectKeys[i] = info; + } + + task.done = true; + }); + } + } + + static void ProcessUnUsedEffectKeys() + { + var lines = new List<string>(File.ReadAllLines(Application.dataPath + "/ResourcesOut/Refdata/Config/Effect.txt")); + var deleteLines = new List<string>(); + var unUsedEffectKeys = new List<string>(); + foreach (var task in tasks) + { + foreach (var iconkey in task.effectKeys) + { + if (iconkey.unused) + { + unUsedEffectKeys.Add(iconkey.key); + } + } + } + + for (int i = lines.Count - 1; i >= 3; i--) + { + var contents = lines[i].Split('\t'); + if (!contents.IsNullOrEmpty()) + { + if (unUsedEffectKeys.Contains(contents[0])) + { + deleteLines.Add(lines[i]); + lines.RemoveAt(i); + } + } + } + + File.WriteAllLines(Application.dataPath + "/鍒犻櫎鐨凟ffect琛ㄩ厤缃�.txt", deleteLines.ToArray()); + File.WriteAllLines(Application.dataPath + "/ResourcesOut/Refdata/Config/Effect.txt", lines.ToArray()); + } + + static Dictionary<string, List<string>> GetEffectKeyMap() + { + var lines = File.ReadAllLines(Application.dataPath + "/Editor/Config/TxtEffectKey.txt"); + var map = new Dictionary<string, List<string>>(); + + for (int i = 1; i < lines.Length; i++) + { + var line = lines[i]; + var contents = new List<string>(line.Split('\t')); + if (!contents.IsNullOrEmpty() && contents.Count >= 2) + { + var fields = map[contents[0]] = new List<string>(); + fields.AddRange(contents.GetRange(1, contents.Count - 1)); + } + } + + return map; + } + + static List<EffectKeyInfo> GetOriginalEffectKeys() + { + var lines = File.ReadAllLines(Application.dataPath + "/ResourcesOut/Refdata/Config/Effect.txt"); + var effectKeys = new List<EffectKeyInfo>(); + for (int i = 3; i < lines.Length; i++) + { + var contents = lines[i].Split('\t'); + if (!contents.IsNullOrEmpty()) + { + effectKeys.Add(new EffectKeyInfo() { key = contents[0], folder = contents[1] }); + } + } + + return effectKeys; + } + + static List<Column> GetAllEffectKeyRefrences() + { + var files = FileExtersion.GetFileInfos(Application.dataPath + "/ResourcesOut/Refdata/Config", new string[] { "*.txt", "*.TXT" }); + + var columns = new List<Column>(); + foreach (var file in files) + { + var nameWithoutExtension = Path.GetFileNameWithoutExtension(file.FullName); + if (!iconKeyMap.ContainsKey(nameWithoutExtension)) + { + continue; + } + + var lines = File.ReadAllLines(file.FullName); + var fields0 = new List<string>(lines[0].Split('\t')); + var fields1 = new List<string>(lines[1].Split('\t')); + var refrences = iconKeyMap[nameWithoutExtension]; + foreach (var refrence in refrences) + { + var name = string.Empty; + var index = fields0.IndexOf(refrence); + if (index != -1) + { + name = fields0[index]; + } + else + { + index = fields1.IndexOf(refrence); + if (index != -1) + { + name = fields1[index]; + } + } + + if (index == -1) + { + continue; + } + + var column = new Column() + { + name = name, + values = new List<string>() + }; + + columns.Add(column); + for (int i = 1; i < lines.Length; i++) + { + var line = lines[i]; + var contents = line.Split('\t'); + column.values.Add(contents[index]); + } + } + + } + + return columns; + } + + static List<string> GetAllCSharpFileContents() + { + var files = FileExtersion.GetFileInfos(Application.dataPath + "/Scripts", new string[] { "*.cs" }); + var contents = new List<string>(); + + var count = 0; + foreach (var file in files) + { + count++; + EditorUtility.DisplayProgressBar("璇诲彇浠g爜鏂囦欢", "姝e湪璇诲彇浠g爜鏂囦欢", (float)count / files.Count); + contents.Add(File.ReadAllText(file.FullName)); + } + + EditorUtility.ClearProgressBar(); + return contents; + } + + static List<UIEffect> GetEffectComponents() + { + var guids = new List<string>(); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot1 })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot2 })); + guids.AddRange(AssetDatabase.FindAssets("t:prefab", new string[] { uiroot3 })); + + var assetPaths = new List<string>(); + foreach (var item in guids) + { + assetPaths.Add(AssetDatabase.GUIDToAssetPath(item)); + } + + var count = 0; + var uieffects = new List<UIEffect>(); + foreach (var path in assetPaths) + { + count++; + EditorUtility.DisplayProgressBar("鏀堕泦UIEffect", "姝e湪鎼滅储Prefab涓婄殑UIEffect", (float)count / assetPaths.Count); + var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(path); + if (gameObject == null) + { + continue; + } + + var components = gameObject.GetComponentsInChildren<UIEffect>(true); + if (!components.IsNullOrEmpty()) + { + uieffects.AddRange(components); + } + } + + EditorUtility.ClearProgressBar(); + return uieffects; + } + + static bool ContainByTables(string key, ref List<Column> columns) + { + foreach (var column in columns) + { + foreach (var value in column.values) + { + if (Regex.IsMatch(value, key)) + { + return true; + } + } + } + + return false; + } + + static bool ContainByCSharpFile(string key, ref List<string> csharpContents) + { + var pattern1 = string.Format(@"SFXPlayUtility.Instance.PlayBattleEffect.*{0}.*\);", key); + var pattern2 = string.Format(@"SFXPlayUtility.Instance.PlayEffectAsync.*{0}.*\);", key); + + foreach (var content in csharpContents) + { + if (Regex.IsMatch(content, pattern1)) + { + return true; + } + + if (Regex.IsMatch(content, pattern2)) + { + return true; + } + } + + return false; + } + + static bool ContainByPrefab(string key, ref List<UIEffect> uieffects) + { + foreach (var uieffect in uieffects) + { + if (uieffect.effect.ToString() == key) + { + return true; + } + } + + return false; + } + + static void OnUpdate() + { + var done = true; + completedTaskCount = 0; + foreach (var task in tasks) + { + completedTaskCount += task.completed; + if (!task.done) + { + done = false; + } + } + + EditorUtility.DisplayProgressBar("鍒嗘瀽鏃犵敤EffectKey", + string.Format("姝e湪鍒嗘瀽绗瑊0}涓狤ffectKey,鍏辫{1}涓�", completedTaskCount + 1, taskCount), + (float)completedTaskCount / taskCount); + + if (done) + { + EditorUtility.ClearProgressBar(); + ProcessUnUsedEffectKeys(); + EditorApplication.update -= OnUpdate; + } + } + + struct Column + { + public string name; + public List<string> values; + } + + struct EffectKeyInfo + { + public string key; + public string folder; + public bool unused; + } + + class AnalyzeTask + { + public int total; + public int completed; + public bool done; + public List<EffectKeyInfo> effectKeys; + + public AnalyzeTask() + { + effectKeys = new List<EffectKeyInfo>(); + } + + public void Add(EffectKeyInfo key) + { + effectKeys.Add(key); + } + } + +} + + diff --git a/Assets/Editor/Tool/EffectAssetCheck.cs.meta b/Assets/Editor/Tool/EffectAssetCheck.cs.meta new file mode 100644 index 0000000..342c1b1 --- /dev/null +++ b/Assets/Editor/Tool/EffectAssetCheck.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6084c3e1e032eb547bb56eb8a745d4bd +timeCreated: 1555386504 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Tool/UIAssetCheck.cs b/Assets/Editor/Tool/UIAssetCheck.cs index 1f1d878..694e62f 100644 --- a/Assets/Editor/Tool/UIAssetCheck.cs +++ b/Assets/Editor/Tool/UIAssetCheck.cs @@ -496,6 +496,7 @@ static void ProcessUnUsedIconKeys() { var lines = new List<string>(File.ReadAllLines(Application.dataPath + "/ResourcesOut/Refdata/Config/Icon.txt")); + var deleteLines = new List<string>(); var unUsedIconKeys = new List<string>(); foreach (var task in tasks) { @@ -515,11 +516,13 @@ { if (unUsedIconKeys.Contains(contents[0])) { + deleteLines.Add(lines[i]); lines.RemoveAt(i); } } } + File.WriteAllLines(Application.dataPath + "/鍒犻櫎鐨処con琛ㄩ厤缃�.txt", deleteLines.ToArray()); File.WriteAllLines(Application.dataPath + "/ResourcesOut/Refdata/Config/Icon.txt", lines.ToArray()); } @@ -562,9 +565,13 @@ { var files = FileExtersion.GetFileInfos(Application.dataPath + "/ResourcesOut/Refdata/Config", new string[] { "*.txt", "*.TXT" }); + var count = 0; var columns = new List<Column>(); foreach (var file in files) { + count++; + EditorUtility.DisplayProgressBar("瑙f瀽閰嶇疆鏂囦欢", "姝e湪瑙f瀽閰嶇疆鏂囦欢", (float)count / files.Count); + var nameWithoutExtension = Path.GetFileNameWithoutExtension(file.FullName); if (!iconKeyMap.ContainsKey(nameWithoutExtension)) { @@ -614,6 +621,7 @@ } + EditorUtility.ClearProgressBar(); return columns; } @@ -622,10 +630,15 @@ var files = FileExtersion.GetFileInfos(Application.dataPath + "/Scripts", new string[] { "*.cs" }); var contents = new List<string>(); + var count = 0; foreach (var file in files) { + count++; + EditorUtility.DisplayProgressBar("璇诲彇浠g爜鏂囦欢","姝e湪璇诲彇浠g爜鏂囦欢",(float) count/files.Count); contents.Add(File.ReadAllText(file.FullName)); } + + EditorUtility.ClearProgressBar(); return contents; } @@ -643,12 +656,16 @@ assetPaths.Add(AssetDatabase.GUIDToAssetPath(item)); } + var count = 0; prefabTexts = new List<string>(); foreach (var path in assetPaths) { + count++; + EditorUtility.DisplayProgressBar("璇诲彇棰勭疆浣撴枃鏈�", "姝e湪璇诲彇棰勭疆浣撴枃鏈�", (float)count / assetPaths.Count); prefabTexts.Add(File.ReadAllText(Application.dataPath + path.Substring(6, path.Length - 6))); } + EditorUtility.ClearProgressBar(); return prefabTexts; } -- Gitblit v1.8.0