Unity 框架

EditorGlobalTool.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Reflection.Emit;
  7. using UnityEditor;
  8. using UnityEditor.Callbacks;
  9. using UnityEditor.SceneManagement;
  10. using UnityEngine;
  11. using UnityEngine.EventSystems;
  12. using UnityEngine.SceneManagement;
  13. using UnityEngine.UI;
  14. using Object = UnityEngine.Object;
  15. namespace TFramework
  16. {
  17. /// <summary>
  18. /// 编辑器全局工具类
  19. /// </summary>
  20. public class EditorGlobalTool
  21. {
  22. public static Folder Code = new Folder(null, "Code", "Scenes");
  23. public static Folder[] ProjectStructureFolder = new Folder[]
  24. {
  25. new Folder(null,"Plugins"),
  26. new Folder(null,"Ued","Scenes","Model","UI","Materials","Textures","Animations","Sound","Fonts","Video","Prefabs"),
  27. new Folder(null,"StreamingAssets","PDF","JSON","TEXT")
  28. };
  29. public static Folder Env1 = new Folder(Code, "Env1", "Scripts", "Animations", "Animators", "Audios", "Materials", "Fonts", "FX", "Shaders", "Sprites", "Textures", "Prefabs", "Resources", "Data");
  30. public static Folder DataFolder = new Folder(Env1, "Editor", "Data");
  31. #region 工具
  32. /// <summary>
  33. /// 快捷构建项目结构
  34. /// </summary>
  35. [MenuItem("Assets/Create/TFramework/构建项目结构", false, 2)]
  36. public static void CreateProjectStructure()
  37. {
  38. CreateFolder(Code);
  39. for (int i = 0; i < ProjectStructureFolder.Length; i++)
  40. CreateFolder(ProjectStructureFolder[i]);
  41. CreateFolder(Env1);
  42. CreateFolder(DataFolder);
  43. }
  44. private static void CreateFolder(Folder folder)
  45. {
  46. if (!AssetDatabase.IsValidFolder(folder.Path))
  47. {
  48. AssetDatabase.CreateFolder(folder.Parent != null ? folder.Parent.Path : "Assets", folder.Name);
  49. }
  50. for (int i = 0; i < folder.SubFolders.Count; i++)
  51. {
  52. CreateFolder(folder.SubFolders[i]);
  53. }
  54. }
  55. [MenuItem("TFramework/Tools/一键清理缺失脚本")]
  56. public static void CleanMissingScript()
  57. {
  58. int sum = 0;
  59. GameObject[] gos = Selection.gameObjects;
  60. for (int i = 0; i < gos.Length; i++)
  61. {
  62. foreach (var item in gos[i].GetComponentsInChildren<Transform>(true))
  63. {
  64. if(GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(item.gameObject)>0)
  65. {
  66. int r = 0;
  67. r = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(item.gameObject);
  68. if (PrefabUtility.GetPrefabAssetType(item.gameObject) != PrefabAssetType.NotAPrefab)
  69. {
  70. PrefabUtility.SaveAsPrefabAssetAndConnect(item.gameObject, GetPrefabAssetPath(item.gameObject), InteractionMode.AutomatedAction);
  71. AssetDatabase.Refresh();
  72. }
  73. else
  74. {
  75. EditorUtility.SetDirty(item);
  76. AssetDatabase.Refresh();
  77. }
  78. sum += r;
  79. Log.Info("清除了物体:" + item.name + " 的一个missing脚本");
  80. }
  81. }
  82. }
  83. Log.Info("清除完成,清理个数:" + sum);
  84. }
  85. #endregion
  86. #region 创建脚本
  87. [MenuItem("Assets/Create/TFramework/创建UIScript", false, 100)]
  88. public static void CreateUIScript()
  89. {
  90. CreateScriptFromTemplate.Create<CreateGeneralScript>(EditorConfigFile.CreateUIScriptTemplatePath, "NewUIScript",
  91. EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D);
  92. }
  93. [MenuItem("Assets/Create/创建C# Script", false, 80)]
  94. public static void CreateScript()
  95. {
  96. CreateScriptEdit.OpenWin();
  97. }
  98. #endregion
  99. #region 快捷操作
  100. static GenericMenu pathMenu;
  101. [MenuItem("GameObject/TFramework/拷贝层级路径", false, 20)]
  102. public static void GetObjPath()
  103. {
  104. EditorApplication.delayCall -= ShowCustomMenu;
  105. EditorApplication.delayCall += ShowCustomMenu;
  106. }
  107. private static void ShowCustomMenu()
  108. {
  109. Transform obj = Selection.activeTransform;
  110. Transform parent = obj.parent;
  111. pathMenu = new GenericMenu();
  112. string path = obj.name;
  113. while (parent != null)
  114. {
  115. path = parent.name + "/" + path;
  116. parent = parent.parent;
  117. string p = path.Replace("/", ">");
  118. pathMenu.AddItem(new GUIContent(p), false, () =>
  119. {
  120. GUIUtility.systemCopyBuffer = p.Replace(">", "/");
  121. });
  122. }
  123. var window = EditorWindow.focusedWindow;
  124. if (window != null)
  125. {
  126. // 获取窗口视图的中心点
  127. Vector2 centerPosition = new Vector2(window.position.width / 2, window.position.height / 2);
  128. pathMenu.DropDown(new Rect(centerPosition, Vector2.zero));
  129. }
  130. }
  131. #endregion
  132. #region 代码调用
  133. private static HashSet<string> EditorAssemblies = new HashSet<string>()
  134. {
  135. "Assembly-CSharp-Editor","UnityEditor","UnityEditor.SceneManagement","UnityEditorInternal","TFramework.Editor","UnityEditor.CoreModule"
  136. };
  137. /// <summary>
  138. /// 获取编辑器程序集中所有类型
  139. /// </summary>
  140. /// <returns></returns>
  141. public static List<Type> GetTypeInEditorAssemblies()
  142. {
  143. List<Type> types = new List<Type>();
  144. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  145. for (int i = 0; i < assemblys.Length; i++)
  146. {
  147. if (EditorAssemblies.Contains(assemblys[i].GetName().Name))
  148. {
  149. types.AddRange(assemblys[i].GetTypes());
  150. }
  151. }
  152. return types;
  153. }
  154. /// <summary>
  155. /// 获取编辑器程序集中符合条件的类型
  156. /// </summary>
  157. /// <param name="filter">条件</param>
  158. /// <returns></returns>
  159. public static List<Type> GetTypeInEditorAssemblies(TFunc<Type, bool> filter)
  160. {
  161. List<Type> types = new List<Type>();
  162. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  163. for (int i = 0; i < assemblys.Length; i++)
  164. {
  165. if (EditorAssemblies.Contains(assemblys[i].GetName().Name))
  166. {
  167. Type[] ts = assemblys[i].GetTypes();
  168. foreach (var t in ts)
  169. {
  170. if (filter(t))
  171. {
  172. types.Add(t);
  173. }
  174. }
  175. }
  176. }
  177. return types;
  178. }
  179. /// <summary>
  180. /// 获取编辑器程序集中的类型
  181. /// </summary>
  182. /// <returns></returns>
  183. public static Type GetTypeInEditorAssemblies(string space,string typeName)
  184. {
  185. Type type = null;
  186. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  187. for (int i = 0; i < assemblys.Length; i++)
  188. {
  189. if (EditorAssemblies.Contains(assemblys[i].GetName().Name)&& assemblys[i].GetName().Name==space)
  190. {
  191. Type[] ts = assemblys[i].GetTypes();
  192. foreach (var t in ts)
  193. {
  194. if (t.Name==typeName)
  195. {
  196. type=t;
  197. }
  198. }
  199. }
  200. }
  201. return type;
  202. }
  203. /// <summary>
  204. /// 获取编辑器程序集中符合条件的方法
  205. /// </summary>
  206. /// <param name="filter">条件</param>
  207. /// <returns></returns>
  208. public static List<MethodInfo> GetMethodInEditorAssemblies(TFunc<MethodInfo, bool> filter)
  209. {
  210. List<MethodInfo> methodInfos = new List<MethodInfo>();
  211. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  212. for (int i = 0; i < assemblys.Length; i++)
  213. {
  214. if (EditorAssemblies.Contains(assemblys[i].GetName().Name))
  215. {
  216. foreach (var item in assemblys[i].GetTypes())
  217. {
  218. methodInfos.AddRange(item.GetMethods(filter));
  219. }
  220. }
  221. }
  222. return methodInfos;
  223. }
  224. public static MethodInfo GetMethodInEditorAssemblie(string typeFullName,string methodName)
  225. {
  226. MethodInfo method = null;
  227. Type type = Type.GetType(typeFullName);
  228. if(type!=null)
  229. method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
  230. return method;
  231. }
  232. /// <summary>
  233. /// 获取Hierarchy预制体在Project路径
  234. /// </summary>
  235. /// <param name="gameObject">预制体</param>
  236. /// <returns></returns>
  237. public static string GetPrefabAssetPath(GameObject gameObject)
  238. {
  239. string path = "";
  240. if (PrefabUtility.IsPartOfPrefabAsset(gameObject))
  241. path = AssetDatabase.GetAssetPath(gameObject);
  242. else if(PrefabUtility.IsPartOfPrefabInstance(gameObject))
  243. {
  244. GameObject go = PrefabUtility.GetCorrespondingObjectFromOriginalSource(gameObject);
  245. path = AssetDatabase.GetAssetPath(go);
  246. }
  247. else
  248. {
  249. var prefab = PrefabStageUtility.GetPrefabStage(gameObject);
  250. if (prefab != null)
  251. path = prefab.assetPath;
  252. }
  253. return path;
  254. }
  255. /// <summary>
  256. /// 添加自定义宏
  257. /// </summary>
  258. /// <param name="symbol"></param>
  259. public static void AddDefineSymbols(string symbol)
  260. {
  261. BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
  262. string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
  263. if (symbols.Split(';').Contains(symbol)) return;
  264. symbols = string.IsNullOrEmpty(symbols) ? symbol : symbols += $";{symbol}";
  265. PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, symbols);
  266. }
  267. /// <summary>
  268. /// 移除自定义宏
  269. /// </summary>
  270. /// <param name="symbol"></param>
  271. public static void RemoveDefineSymbols(string symbol)
  272. {
  273. BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
  274. string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
  275. List<string> symbolList = new List<string>(symbols.Split(';'));
  276. if (symbolList.Contains(symbol))
  277. {
  278. symbolList.Remove(symbol);
  279. }
  280. symbols = "";
  281. symbolList.ForEach(p => symbols += p + ";");
  282. PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, symbols);
  283. }
  284. #endregion
  285. }
  286. public class Folder
  287. {
  288. public Folder Parent;
  289. public List<Folder> SubFolders;
  290. public string Name;
  291. public string Path;
  292. public string FullPath;
  293. public Folder(Folder parent, string name, params string[] subs)
  294. {
  295. Parent = parent;
  296. SubFolders = new List<Folder>();
  297. Name = name;
  298. Path = Parent == null ? ("Assets/" + Name) : (Parent.Path + "/" + Name);
  299. FullPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/")) + "/" + Path;
  300. if (Parent != null)
  301. {
  302. Parent.SubFolders.Add(this);
  303. }
  304. for (int i = 0; i < subs.Length; i++)
  305. {
  306. new Folder(this, subs[i]);
  307. }
  308. }
  309. }
  310. }