using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Reflection.Emit; using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; using Object = UnityEngine.Object; namespace TFramework { /// /// 编辑器全局工具类 /// public class EditorGlobalTool { public static Folder Code = new Folder(null, "Code", "Scenes"); public static Folder[] ProjectStructureFolder = new Folder[] { new Folder(null,"Plugins"), new Folder(null,"Ued","Scenes","Model","UI","Materials","Textures","Animations","Sound","Fonts","Video","Prefabs"), new Folder(null,"StreamingAssets","PDF","JSON","TEXT") }; public static Folder Env1 = new Folder(Code, "Env1", "Scripts", "Animations", "Animators", "Audios", "Materials", "Fonts", "FX", "Shaders", "Sprites", "Textures", "Prefabs", "Resources", "Data"); public static Folder DataFolder = new Folder(Env1, "Editor", "Data"); #region 工具 /// /// 快捷构建项目结构 /// [MenuItem("Assets/Create/TFramework/构建项目结构", false, 2)] public static void CreateProjectStructure() { CreateFolder(Code); for (int i = 0; i < ProjectStructureFolder.Length; i++) CreateFolder(ProjectStructureFolder[i]); CreateFolder(Env1); CreateFolder(DataFolder); } private static void CreateFolder(Folder folder) { if (!AssetDatabase.IsValidFolder(folder.Path)) { AssetDatabase.CreateFolder(folder.Parent != null ? folder.Parent.Path : "Assets", folder.Name); } for (int i = 0; i < folder.SubFolders.Count; i++) { CreateFolder(folder.SubFolders[i]); } } [MenuItem("TFramework/Tools/一键清理缺失脚本")] public static void CleanMissingScript() { int sum = 0; GameObject[] gos = Selection.gameObjects; for (int i = 0; i < gos.Length; i++) { foreach (var item in gos[i].GetComponentsInChildren(true)) { if(GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(item.gameObject)>0) { int r = 0; r = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(item.gameObject); if (PrefabUtility.GetPrefabAssetType(item.gameObject) != PrefabAssetType.NotAPrefab) { PrefabUtility.SaveAsPrefabAssetAndConnect(item.gameObject, GetPrefabAssetPath(item.gameObject), InteractionMode.AutomatedAction); AssetDatabase.Refresh(); } else { EditorUtility.SetDirty(item); AssetDatabase.Refresh(); } sum += r; Log.Info("清除了物体:" + item.name + " 的一个missing脚本"); } } } Log.Info("清除完成,清理个数:" + sum); } #endregion #region 创建脚本 [MenuItem("Assets/Create/TFramework/创建UIScript", false, 100)] public static void CreateUIScript() { CreateScriptFromTemplate.Create(EditorConfigFile.CreateUIScriptTemplatePath, "NewUIScript", EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D); } [MenuItem("Assets/Create/创建C# Script", false, 80)] public static void CreateScript() { CreateScriptEdit.OpenWin(); } #endregion #region 快捷操作 static GenericMenu pathMenu; [MenuItem("GameObject/TFramework/拷贝层级路径", false, 20)] public static void GetObjPath() { EditorApplication.delayCall -= ShowCustomMenu; EditorApplication.delayCall += ShowCustomMenu; } private static void ShowCustomMenu() { Transform obj = Selection.activeTransform; Transform parent = obj.parent; pathMenu = new GenericMenu(); string path = obj.name; while (parent != null) { path = parent.name + "/" + path; parent = parent.parent; string p = path.Replace("/", ">"); pathMenu.AddItem(new GUIContent(p), false, () => { GUIUtility.systemCopyBuffer = p.Replace(">", "/"); }); } var window = EditorWindow.focusedWindow; if (window != null) { // 获取窗口视图的中心点 Vector2 centerPosition = new Vector2(window.position.width / 2, window.position.height / 2); pathMenu.DropDown(new Rect(centerPosition, Vector2.zero)); } } #endregion #region 代码调用 private static HashSet EditorAssemblies = new HashSet() { "Assembly-CSharp-Editor","UnityEditor","UnityEditor.SceneManagement","UnityEditorInternal","TFramework.Editor","UnityEditor.CoreModule" }; /// /// 获取编辑器程序集中所有类型 /// /// public static List GetTypeInEditorAssemblies() { List types = new List(); Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblys.Length; i++) { if (EditorAssemblies.Contains(assemblys[i].GetName().Name)) { types.AddRange(assemblys[i].GetTypes()); } } return types; } /// /// 获取编辑器程序集中符合条件的类型 /// /// 条件 /// public static List GetTypeInEditorAssemblies(TFunc filter) { List types = new List(); Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblys.Length; i++) { if (EditorAssemblies.Contains(assemblys[i].GetName().Name)) { Type[] ts = assemblys[i].GetTypes(); foreach (var t in ts) { if (filter(t)) { types.Add(t); } } } } return types; } /// /// 获取编辑器程序集中的类型 /// /// public static Type GetTypeInEditorAssemblies(string space,string typeName) { Type type = null; Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblys.Length; i++) { if (EditorAssemblies.Contains(assemblys[i].GetName().Name)&& assemblys[i].GetName().Name==space) { Type[] ts = assemblys[i].GetTypes(); foreach (var t in ts) { if (t.Name==typeName) { type=t; } } } } return type; } /// /// 获取编辑器程序集中符合条件的方法 /// /// 条件 /// public static List GetMethodInEditorAssemblies(TFunc filter) { List methodInfos = new List(); Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblys.Length; i++) { if (EditorAssemblies.Contains(assemblys[i].GetName().Name)) { foreach (var item in assemblys[i].GetTypes()) { methodInfos.AddRange(item.GetMethods(filter)); } } } return methodInfos; } public static MethodInfo GetMethodInEditorAssemblie(string typeFullName,string methodName) { MethodInfo method = null; Type type = Type.GetType(typeFullName); if(type!=null) method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); return method; } /// /// 获取Hierarchy预制体在Project路径 /// /// 预制体 /// public static string GetPrefabAssetPath(GameObject gameObject) { string path = ""; if (PrefabUtility.IsPartOfPrefabAsset(gameObject)) path = AssetDatabase.GetAssetPath(gameObject); else if(PrefabUtility.IsPartOfPrefabInstance(gameObject)) { GameObject go = PrefabUtility.GetCorrespondingObjectFromOriginalSource(gameObject); path = AssetDatabase.GetAssetPath(go); } else { var prefab = PrefabStageUtility.GetPrefabStage(gameObject); if (prefab != null) path = prefab.assetPath; } return path; } /// /// 添加自定义宏 /// /// public static void AddDefineSymbols(string symbol) { BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); if (symbols.Split(';').Contains(symbol)) return; symbols = string.IsNullOrEmpty(symbols) ? symbol : symbols += $";{symbol}"; PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, symbols); } /// /// 移除自定义宏 /// /// public static void RemoveDefineSymbols(string symbol) { BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); List symbolList = new List(symbols.Split(';')); if (symbolList.Contains(symbol)) { symbolList.Remove(symbol); } symbols = ""; symbolList.ForEach(p => symbols += p + ";"); PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, symbols); } #endregion } public class Folder { public Folder Parent; public List SubFolders; public string Name; public string Path; public string FullPath; public Folder(Folder parent, string name, params string[] subs) { Parent = parent; SubFolders = new List(); Name = name; Path = Parent == null ? ("Assets/" + Name) : (Parent.Path + "/" + Name); FullPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/")) + "/" + Path; if (Parent != null) { Parent.SubFolders.Add(this); } for (int i = 0; i < subs.Length; i++) { new Folder(this, subs[i]); } } } }