| //------------------------------------------------------------------ | 
| //本文件中的工具提供在编辑器环境下,快速整理特效相关的资源 | 
| //------------------------------------------------------------------- | 
|   | 
| 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("读取预置体", "正在读取预置体文本", (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("获取特效", "正在获取特效预置体", (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("正在删除第{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("正在分析第{0}个Effect,共计{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 string soskillroot = "Assets/ResourcesOut/Refdata/ScriptableObject/SoSkill"; | 
|     static string newbieguideroot = "Assets/ResourcesOut/Refdata/ScriptableObject/SoNewBieGuide"; | 
|   | 
|     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<NewBieGuideScriptableObject> newbieGuides = new List<NewBieGuideScriptableObject>(); | 
|     static List<SoSkill> soSkills = new List<SoSkill>(); | 
|     static List<AnalyzeTask> tasks = new List<AnalyzeTask>(); | 
|     static string ignorekeys = string.Empty; | 
|   | 
|     [MenuItem("程序/Effect Assets/移除无用的EffectKey")] | 
|     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(); | 
|         soSkills = GetSoSkills(); | 
|         newbieGuides = GetNewbieGuides(); | 
|         ignorekeys = GetIngoreKeys(); | 
|   | 
|         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 (IsIgnoreKey(info.key, ref ignorekeys)) | 
|                     { | 
|                         Debug.LogFormat("找到一个不要删除的 effect key:{0}", info.key); | 
|                         continue; | 
|                     } | 
|   | 
|                     if (ContainBySoSkills(info.key, ref soSkills)) | 
|                     { | 
|                         Debug.LogFormat("找到一个被soskill依赖的 effect key:{0}", info.key); | 
|                         continue; | 
|                     } | 
|   | 
|                     if (ContainByNewbieGuides(info.key, ref newbieGuides)) | 
|                     { | 
|                         Debug.LogFormat("找到一个被新手引导依赖的 effect key:{0}", info.key); | 
|                         continue; | 
|                     } | 
|   | 
|                     if (ContainByPrefab(info.key, ref uieffects)) | 
|                     { | 
|                         Debug.LogFormat("找到一个被prefab依赖的 effect key:{0}", info.key); | 
|                         continue; | 
|                     } | 
|   | 
|                     if (ContainByTables(info.key, ref iconKeyRefrences)) | 
|                     { | 
|                         Debug.LogFormat("找到一个被其他配置配件引用的 effect key:{0}", info.key); | 
|                         continue; | 
|                     } | 
|   | 
|                     if (ContainByCSharpFile(info.key, ref csharpFileContents)) | 
|                     { | 
|                         Debug.LogFormat("找到一个写在C#文件中的 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 + "/删除的Effect表配置.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("读取代码文件", "正在读取代码文件", (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", "正在搜索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 List<SoSkill> GetSoSkills() | 
|     { | 
|         var guids = new List<string>(); | 
|         guids.AddRange(AssetDatabase.FindAssets("t:ScriptableObject", new string[] { soskillroot })); | 
|   | 
|         var assetPaths = new List<string>(); | 
|         foreach (var item in guids) | 
|         { | 
|             assetPaths.Add(AssetDatabase.GUIDToAssetPath(item)); | 
|         } | 
|   | 
|         var soskills = new List<SoSkill>(); | 
|         foreach (var path in assetPaths) | 
|         { | 
|             var soskill = AssetDatabase.LoadAssetAtPath<SoSkill>(path); | 
|             if (soskill != null) | 
|             { | 
|                 soskills.Add(soskill); | 
|             } | 
|         } | 
|   | 
|         return soskills; | 
|     } | 
|   | 
|     static List<NewBieGuideScriptableObject> GetNewbieGuides() | 
|     { | 
|         var guids = new List<string>(); | 
|         guids.AddRange(AssetDatabase.FindAssets("t:ScriptableObject", new string[] { newbieguideroot })); | 
|   | 
|         var assetPaths = new List<string>(); | 
|         foreach (var item in guids) | 
|         { | 
|             assetPaths.Add(AssetDatabase.GUIDToAssetPath(item)); | 
|         } | 
|   | 
|         var newbieguides = new List<NewBieGuideScriptableObject>(); | 
|         foreach (var path in assetPaths) | 
|         { | 
|             var so = AssetDatabase.LoadAssetAtPath<NewBieGuideScriptableObject>(path); | 
|             if (newbieguides != null) | 
|             { | 
|                 newbieguides.Add(so); | 
|             } | 
|         } | 
|   | 
|         return newbieguides; | 
|     } | 
|   | 
|     static string GetIngoreKeys() | 
|     { | 
|         return File.ReadAllText(Application.dataPath + "/Editor/Config/DeleteEffectExcludeKey.txt"); | 
|     } | 
|   | 
|     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); | 
|         var pattern3 = string.Format(@"SFXPlayUtility.Instance.PlayWithEulerAngle.*{0}", key); | 
|         var pattern4 = string.Format(@"SFXPlayUtility.Instance.Play.*{0}", key); | 
|   | 
|         foreach (var content in csharpContents) | 
|         { | 
|             if (Regex.IsMatch(content, pattern1)) | 
|             { | 
|                 return true; | 
|             } | 
|   | 
|             if (Regex.IsMatch(content, pattern2)) | 
|             { | 
|                 return true; | 
|             } | 
|   | 
|             if (Regex.IsMatch(content, pattern3)) | 
|             { | 
|                 return true; | 
|             } | 
|   | 
|             if (Regex.IsMatch(content, pattern4)) | 
|             { | 
|                 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 bool ContainBySoSkills(string key, ref List<SoSkill> soSkills) | 
|     { | 
|         foreach (var soskill in soSkills) | 
|         { | 
|             foreach (var frameEvent in soskill.animationEventList) | 
|             { | 
|                 if (frameEvent.frameEventType == E_FrameEventType.OnPlayEffect) | 
|                 { | 
|                     if (frameEvent.intParam.ToString() == key) | 
|                     { | 
|                         return true; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|   | 
|         return false; | 
|     } | 
|   | 
|     static bool ContainByNewbieGuides(string key, ref List<NewBieGuideScriptableObject> newbieGuides) | 
|     { | 
|         foreach (var newbieGuide in newbieGuides) | 
|         { | 
|             if (newbieGuide.effect2.ToString() == key) | 
|             { | 
|                 return true; | 
|             } | 
|         } | 
|   | 
|         return false; | 
|     } | 
|   | 
|     static bool IsIgnoreKey(string key, ref string ignores) | 
|     { | 
|         return Regex.IsMatch(ignores, key); | 
|     } | 
|   | 
|     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("正在分析第{0}个EffectKey,共计{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); | 
|         } | 
|     } | 
|   | 
| } |