using UnityEngine; using System.Collections; using UnityEditor; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using GameEditor.Core; using GameLogic; using System.Collections.Generic; using System.Threading; public class FindReferences { static string withoutExtensions = "*.prefab*.unity*.mat*.shader*.asset*.controller"; [MenuItem("Assets/Find References", false, 10)] static private void Find() { EditorSettings.serializationMode = SerializationMode.ForceText; string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (Selection.activeObject is DefaultAsset) { Debug.Log("文件夹路径:" + path); System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch(); time.Start(); string[] files = Directory.GetFiles(path).Where(s => !s.EndsWith(".meta")).ToArray(); string[] ffs = Directory.GetFiles(AppConst.GameResRealPath, "*.*", SearchOption.AllDirectories) .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray(); Dictionary> dic = new Dictionary>(); string[] guids = new string[files.Length]; for (int i = 0; i < files.Length; i++) { dic[files[i]] = new List(); guids[i] = AssetDatabase.AssetPathToGUID(files[i]); } string FilePath = null; object lockObj = new object(); int count = 0; EditorApplication.update = () => { if (count < ffs.Length) { EditorUtility.DisplayCancelableProgressBar(string.Format("匹配资源中({0}/{1})", count, ffs.Length), FilePath, (float)count / ffs.Length); } else { EditorApplication.update = null; for (int i = 0; i < files.Length; i++) { Debug.Log("【资源路径】:" + files[i], AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(files[i]))); for (int j = 0; j < dic[files[i]].Count; j++) { var obj = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(dic[files[i]][j])); var obj2 = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(files[i])); Debug.LogError("引用路径:" + dic[files[i]][j], obj); var extension = Path.GetExtension(dic[files[i]][j]); if (extension == ".prefab") { var gameObj = obj as GameObject; CheckResRef(gameObj.transform, gameObj.transform, obj2.name); DebugChildName(gameObj.transform, gameObj.transform, obj2.name); } } } EditorUtility.ClearProgressBar(); Debug.Log("匹配结束"); time.Stop(); Debug.LogError("耗时:" + time.ElapsedMilliseconds); } }; for (int i = 0; i < ffs.Length; i++) { int index = i; ThreadPool.QueueUserWorkItem(q => { string file = File.ReadAllText(ffs[index]); for (int j = 0; j < files.Length; j++) { if (Regex.IsMatch(file, guids[j])) { dic[files[j]].Add(ffs[index]); } } lock (lockObj) { count++; FilePath = ffs[index]; } }); } } else { if (!string.IsNullOrEmpty(path)) { string guid = AssetDatabase.AssetPathToGUID(path); string[] files = Directory.GetFiles(AppConst.GameResRealPath, "*.*", SearchOption.AllDirectories) .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray(); System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch(); time.Start(); string FilePath = null; object lockObj = new object(); int count = 0; List list = new List(); EditorApplication.update = () => { if (count < files.Length) { EditorUtility.DisplayCancelableProgressBar(string.Format("匹配资源中({0}/{1})", count, files.Length), FilePath, (float)count / files.Length); } else { EditorApplication.update = null; Debug.Log("【资源路径】:" + path, AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(path))); for (int i = 0; i < list.Count; i++) { var obj = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(list[i])); Debug.LogError("引用路径:" + list[i], obj); var extension = Path.GetExtension(list[i]); if (extension == ".prefab") { var gameObj = obj as GameObject; CheckResRef(gameObj.transform, gameObj.transform, Selection.activeObject.name); DebugChildName(gameObj.transform, gameObj.transform, Selection.activeObject.name); } } EditorUtility.ClearProgressBar(); Debug.Log("匹配结束"); time.Stop(); Debug.LogError("耗时:" + time.ElapsedMilliseconds); } }; for (int i = 0; i < files.Length; i++) { int index = i; ThreadPool.QueueUserWorkItem(q => { string file = File.ReadAllText(files[index]); if (Regex.IsMatch(file, guid)) { list.Add(files[index]); } lock (lockObj) { count++; FilePath = files[index]; } }); } } } } static void DebugChildName(Transform parent, Transform topParent, string targetName) { for (int i = 0; i < parent.childCount; i++) { var child = parent.GetChild(i); CheckResRef(child, topParent, targetName); if (child.childCount > 0) { DebugChildName(child, topParent, targetName); } } } static void CheckResRef(Transform tran, Transform topParent, string targetName) { bool isShowPath = false; var image = tran.GetComponent(); isShowPath |= image != null && image.sprite != null && image.sprite.name == targetName; var image2 = tran.GetComponent(); isShowPath |= image2 != null && image2.sprite != null && image2.sprite.name == targetName; var text = tran.GetComponent(); isShowPath |= text != null && text.font != null && text.font.name == targetName; var mat = tran.GetComponent(); isShowPath |= mat != null && mat.sharedMaterial != null && mat.sharedMaterial.name == targetName; var anim = tran.GetComponent(); isShowPath |= anim != null && anim.runtimeAnimatorController != null && anim.runtimeAnimatorController.name == targetName; var spine1 = tran.GetComponent(); isShowPath |= spine1 != null && spine1.skeletonDataAsset != null && spine1.skeletonDataAsset.name == targetName; var spine2 = tran.GetComponent(); isShowPath |= spine2 != null && spine2.skeletonDataAsset != null && spine2.skeletonDataAsset.name == targetName; if (isShowPath) { Debug.LogWarning("【预制体内部路径】:" + tran.GetPathToParent(topParent)); } } [MenuItem("Assets/一键绑定动画按钮", false, 10)] static void BindingAnimButton() { if (!EditorUtility.DisplayDialog("提示", "确定修改该资源所关联的按钮组件?注意这会影响所有相关的预设", "确定", "取消")) { return; } string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (!string.IsNullOrEmpty(path)) { string guid = AssetDatabase.AssetPathToGUID(path); string[] files = Directory.GetFiles(AppConst.GameResRealPath, "*.*", SearchOption.AllDirectories) .Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray(); System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch(); time.Start(); string FilePath = null; object lockObj = new object(); int count = 0; List list = new List(); EditorApplication.update = () => { if (count < files.Length) { EditorUtility.DisplayCancelableProgressBar(string.Format("匹配资源中({0}/{1})", count, files.Length), FilePath, (float)count / files.Length); } else { EditorApplication.update = null; Debug.Log("【资源路径】:" + path, AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(path))); var o = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(path)); var anim = AssetDatabase.LoadAssetAtPath("Assets/ManagedResources/PublicArtRes/Animations/CommonButton.controller"); for (int i = 0; i < list.Count; i++) { var obj = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(list[i])); //Debug.LogError("引用路径:" + list[i], obj); var extension = Path.GetExtension(list[i]); if (extension == ".prefab") { var gameObj = obj as GameObject; CheckResRef(gameObj.transform, gameObj.transform, Selection.activeObject.name); DebugChildName(gameObj.transform, gameObj.transform, Selection.activeObject.name); var images = gameObj.GetComponentsInChildren(true); for (int j = 0; j < images.Length; j++) { if (images[j].sprite != null && images[j].sprite.name == o.name) { var btnGo = images[j].gameObject.GetComponent(); if (btnGo != null) { btnGo.transition = UnityEngine.UI.Selectable.Transition.Animation; var ac = btnGo.gameObject.GetComponent(); if (ac == null) { ac = btnGo.gameObject.AddComponent(); } ac.runtimeAnimatorController = anim; } } } AssetDatabase.SaveAssets(); EditorUtility.SetDirty(gameObj); } } AssetDatabase.Refresh(); EditorUtility.ClearProgressBar(); Debug.Log("匹配结束"); time.Stop(); Debug.LogError("耗时:" + time.ElapsedMilliseconds); } }; for (int i = 0; i < files.Length; i++) { int index = i; ThreadPool.QueueUserWorkItem(q => { string file = File.ReadAllText(files[index]); if (Regex.IsMatch(file, guid)) { list.Add(files[index]); } lock (lockObj) { count++; FilePath = files[index]; } }); } } } static string MoveToPath = AppConst.GameResRealPath + "/PublicArtRes/"; [MenuItem("Assets/MoveToPublicRes/Material", false, 10)] static void MoveToPublicResMat() { string path = AssetDatabase.GetAssetPath(Selection.activeObject); string extension = Path.GetExtension(path).ToLower(); if (Selection.activeObject is Material) { File.Move(Application.dataPath + path.Replace("Assets", ""), MoveToPath + "Materials/" + Selection.activeObject.name + extension); File.Move(Application.dataPath + path.Replace("Assets", "") + ".meta", MoveToPath + "Materials/" + Selection.activeObject.name + extension + ".meta"); AssetDatabase.Refresh(); } } [MenuItem("Assets/MoveToPublicRes/Texture", false, 10)] static void MoveToPublicResTex() { string path = AssetDatabase.GetAssetPath(Selection.activeObject); string extension = Path.GetExtension(path).ToLower(); if (Selection.activeObject is Texture) { File.Move(Application.dataPath + path.Replace("Assets", ""), MoveToPath + "Textures/" + Selection.activeObject.name + extension); File.Move(Application.dataPath + path.Replace("Assets", "") + ".meta", MoveToPath + "Textures/" + Selection.activeObject.name + extension + ".meta"); AssetDatabase.Refresh(); } } [MenuItem("Assets/MoveToPublicRes/Model", false, 10)] static void MoveToPublicResMod() { string path = AssetDatabase.GetAssetPath(Selection.activeObject); string extension = Path.GetExtension(path).ToLower(); if (Selection.activeObject is GameObject) { File.Move(Application.dataPath + path.Replace("Assets", ""), MoveToPath + "Models/" + Selection.activeObject.name + extension); File.Move(Application.dataPath + path.Replace("Assets", "") + ".meta", MoveToPath + "Models/" + Selection.activeObject.name + extension + ".meta"); AssetDatabase.Refresh(); } } [MenuItem("Assets/Find References", true)] static private bool VFind() { string path = AssetDatabase.GetAssetPath(Selection.activeObject); return (!string.IsNullOrEmpty(path)); } //[MenuItem("Assets/批量添加粒子层级", false, 10)] static void AddLayer() { int targetLayer = 100; int deltaLayer = -1000; UnityEngine.Events.UnityAction action = go => { var gos = go.GetComponentsInChildren(true); for (int i = 0; i < gos.Length; i++) { int layer = gos[i].GetComponent().sortingOrder; Debug.LogError(layer); if (layer > targetLayer) { gos[i].GetComponent().sortingOrder += deltaLayer; } } var gos2 = go.GetComponentsInChildren(true); for (int i = 0; i < gos2.Length; i++) { int layer = gos2[i].GetComponent().sortingOrder; Debug.LogError(layer); if (layer > targetLayer) { gos2[i].GetComponent().sortingOrder += deltaLayer; } } AssetDatabase.Refresh(); }; if (Selection.activeObject is GameObject) { action(Selection.activeObject as GameObject); } else if (Selection.activeObject is DefaultAsset) { string[] files = Directory.GetFiles(AssetDatabase.GetAssetPath(Selection.activeObject)).Where(s => !s.EndsWith(".meta")).ToArray(); for (int i = 0; i < files.Length; i++) { Debug.LogError("查找路径:" + files[i]); var obj = AssetDatabase.LoadAssetAtPath(GetRelativeAssetsPath(files[i])); if (obj is GameObject) { action(obj as GameObject); } } } } static private string GetRelativeAssetsPath(string path) { return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\', '/'); } [MenuItem("Assets/Find Denpendencies", false, 11)] private static void OnSearchForReferences() { //确保鼠标右键选择的是一个Prefab if (Selection.gameObjects.Length != 1) { return; } var go = Selection.gameObjects[0]; //判断GameObject是否为一个Prefab的引用 if (PrefabUtility.GetPrefabType(go) == PrefabType.Prefab) { //UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(go); string path = AssetDatabase.GetAssetPath(go); var dependencies = AssetDatabase.GetDependencies(path); for (int i = 0; i < dependencies.Length; i++) { Debug.Log("Dependency: " + dependencies[i]); } List list = new List(); for (int i = 0; i < dependencies.Length; i++) { string t1 = dependencies[i].Substring(0, dependencies[i].LastIndexOf('/')); if (t1.Contains("Atlas") && !list.Contains(t1)) { Debug.LogError("Dependency: " + t1); list.Add(t1); } } } } public static string GetGameObjectPath(GameObject obj) { string path = "/" + obj.name; while (obj.transform.parent != null) { obj = obj.transform.parent.gameObject; path = "/" + obj.name + path; } return path; } /// /// /// private static string[] _CommonAtlas = new string[]{ "CommonAtlas", "PopupAtlas", "PublicAtlas", "TagAtlas", "TagButtonAtlas" }; private static bool CheckIsCommonAtlas(string atlasName) { for(int i = 0; i < _CommonAtlas.Length; i++) { if (atlasName.Equals(_CommonAtlas[i])) return true; } return false; } [MenuItem("Tools/检查并移动ui预设中不规范引用的资源")] private static void SearchCommonDependencies() { List assetPaths = new List(); assetPaths.Add("Assets/ManagedResources/Prefabs/UI"); // Dictionary Counter = new Dictionary(); string[] allPath = AssetDatabase.FindAssets("t:Prefab", assetPaths.ToArray()); for (int i = 0; i < allPath.Length; i++) { EditorUtility.DisplayCancelableProgressBar("正在查找", allPath[i], (float)i / allPath.Length); string path = AssetDatabase.GUIDToAssetPath(allPath[i]); Debug.LogError(path); string tarFolder = path.Split('/')[4] + "Atlas"; var dependencies = AssetDatabase.GetDependencies(path); for (int j = 0; j < dependencies.Length; j++) { Debug.Log("Dependency: " + dependencies[j]); if (!dependencies[j].StartsWith("Assets/ManagedResources/Atlas")) continue; // 是公用文件 string[] depArray = dependencies[j].Split('/'); string depFolder = depArray[3]; string subFolder= depArray[4];// 有可能是子文件夹 也有可能是文件名 if (CheckIsCommonAtlas(depFolder)) continue; // 就在自己对应的文件夹内 if (depFolder.Equals(tarFolder)) continue; string resName = depArray[depArray.Length - 1]; int outValue = 0; if(Counter.TryGetValue(resName, out outValue)) { tarFolder = "CommonAtlas"; Counter[resName] = outValue + 1; } else{ Counter.Add(resName, 1); } if (!AssetDatabase.IsValidFolder("Assets/ManagedResources/DynamicAtlas/" + tarFolder)) { AssetDatabase.CreateFolder("Assets/ManagedResources/DynamicAtlas", tarFolder); } if (!AssetDatabase.IsValidFolder("Assets/ManagedResources/DynamicAtlas/" + tarFolder + "/ArtFont")) { AssetDatabase.CreateFolder("Assets/ManagedResources/DynamicAtlas/" + tarFolder, "ArtFont"); } string tarPath = "Assets/ManagedResources/DynamicAtlas/" + tarFolder; if (subFolder == "ArtFont") { tarPath += "/ArtFont"; } tarPath += "/" + resName; AssetDatabase.MoveAsset(dependencies[j], tarPath); Debug.LogWarning("MoveAsset "+ dependencies[j] + " to "+ tarPath); } } EditorUtility.ClearProgressBar(); } // 检查大图资源 [MenuItem("Tools/检查并移动Atlas中过大的资源")] private static void FindBigAtlas() { List assetPaths = new List(); assetPaths.Add("Assets/ManagedResources/Atlas"); string[] allPath = AssetDatabase.FindAssets("t:Texture", assetPaths.ToArray()); for (int i = 0; i < allPath.Length; i++) { EditorUtility.DisplayCancelableProgressBar("正在查找", allPath[i], (float)i / allPath.Length); string path = AssetDatabase.GUIDToAssetPath(allPath[i]); var tex = AssetDatabase.LoadAssetAtPath(path); if(tex.width >= 512 || tex.height > 512) { Debug.LogError(path); string[] depArray = path.Split('/'); string resName = depArray[depArray.Length - 1]; AssetDatabase.MoveAsset(path, "Assets/ManagedResources/DynamicAtlas/"+ resName); } } EditorUtility.ClearProgressBar(); } }