Unity 框架

CreateScriptEdit.cs 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. using TFramework;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Text;
  7. using System.IO;
  8. using System;
  9. using System.Reflection;
  10. using System.Linq;
  11. namespace TFramework
  12. {
  13. public class CreateScriptEdit : EditorWindow
  14. {
  15. private string _scriptName;
  16. string ScriptName
  17. {
  18. get => _scriptName;
  19. set
  20. {
  21. if (_scriptName == value) return;
  22. _scriptName = value;
  23. WritScript();
  24. }
  25. }
  26. private bool _isUserNamespace;
  27. bool IsUserNamespace
  28. {
  29. get => _isUserNamespace;
  30. set
  31. {
  32. if (_isUserNamespace == value) return;
  33. _isUserNamespace = value;
  34. WritScript();
  35. }
  36. }
  37. private string _namespce;
  38. string Namespce
  39. {
  40. get => _namespce;
  41. set
  42. {
  43. if (_namespce == value) return;
  44. _namespce = value;
  45. WritScript();
  46. }
  47. }
  48. private bool _isInheritMonon;
  49. bool IsInheritMono
  50. {
  51. get => _isInheritMonon;
  52. set
  53. {
  54. if (_isInheritMonon == value) return;
  55. _isInheritMonon = value;
  56. WritScript();
  57. }
  58. }
  59. private string _scriptDes;
  60. string ScriptDes
  61. {
  62. get => _scriptDes;
  63. set
  64. {
  65. if (_scriptDes == value) return;
  66. _scriptDes = value;
  67. WritScript();
  68. }
  69. }
  70. [SerializeField]
  71. private StringBuilder _script = new StringBuilder();
  72. [SerializeField]
  73. private DesTempData _tempData;
  74. [SerializeField]
  75. private UserData _userData;
  76. [SerializeField]
  77. private Dictionary<string, string> desFiledDic = new Dictionary<string, string>();
  78. [SerializeField]
  79. private List<string> _keys = new List<string>();
  80. const string TEMPDATAPATH = "Assets/TFramework/Editor/CreateScript/DesTemp/DesTempData.asset";
  81. const string USERDATAPATH = "Assets/TFramework/Editor/UserInfo/UserData.asset";
  82. private Dictionary<string, string> classTypeDic = new Dictionary<string, string>
  83. {
  84. {"类","class" },
  85. {"结构体","struct" },
  86. {"枚举","enum" },
  87. {"接口","interface" }
  88. };
  89. private string classType = string.Empty;
  90. string ClassType
  91. {
  92. get => classType;
  93. set
  94. {
  95. if (classType == value) return;
  96. classType = value;
  97. IsInheritMono = (IsInheritMono && classType == "类");
  98. InheritClass = "None";
  99. GetAllType();
  100. WritScript();
  101. }
  102. }
  103. DesTempData TempData
  104. {
  105. get
  106. {
  107. _tempData = _tempData ??
  108. AssetDatabase.LoadAssetAtPath<DesTempData>(TEMPDATAPATH);
  109. if (_tempData == null)
  110. CreateTempData();
  111. return _tempData;
  112. }
  113. }
  114. UserData User
  115. {
  116. get
  117. {
  118. _userData = _userData ?? AssetDatabase.LoadAssetAtPath<UserData>(USERDATAPATH);
  119. if (_userData == null)
  120. CreateUserData();
  121. return _userData;
  122. }
  123. }
  124. private void CreateUserData()
  125. {
  126. _userData = CreateInstance<UserData>();
  127. AssetDatabase.CreateAsset(_userData, USERDATAPATH);
  128. AssetDatabase.Refresh();
  129. _userData = AssetDatabase.LoadAssetAtPath<UserData>(USERDATAPATH);
  130. }
  131. List<string> selecteMenu = new List<string>();
  132. int _selecteTemp = 0;
  133. int SelecteTemp
  134. {
  135. get => _selecteTemp;
  136. set
  137. {
  138. if (_selecteTemp == value) return;
  139. _selecteTemp = value;
  140. FiedGather();
  141. WritScript();
  142. }
  143. }
  144. GenericMenu classTypeMenu;
  145. GenericMenu inheritClassMenu;
  146. GenericMenu citeMenu;
  147. List<Type> _allType = new List<Type>();
  148. private string _inheritClass;
  149. string InheritClass
  150. {
  151. get => _inheritClass;
  152. set
  153. {
  154. if (_inheritClass == value) return;
  155. _inheritClass = value;
  156. WritScript();
  157. }
  158. }
  159. private static readonly HashSet<Type> IntegerTypes = new HashSet<Type>
  160. {
  161. typeof(byte),
  162. typeof(sbyte),
  163. typeof(short),
  164. typeof(ushort),
  165. typeof(int),
  166. typeof(uint),
  167. typeof(long),
  168. typeof(ulong)
  169. };
  170. private static HashSet<string> Cites = new HashSet<string>();
  171. public static void OpenWin()
  172. {
  173. CreateScriptEdit win = GetWindow<CreateScriptEdit>();
  174. win.minSize = new Vector2(450, 200);
  175. win.titleContent.text = "创建脚本";
  176. win.titleContent.image = EditorGUIUtility.IconContent("cs Script Icon").image;
  177. }
  178. private void OnEnable()
  179. {
  180. RefreshTemp();
  181. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  182. foreach (var ab in assemblys)
  183. foreach (var type in ab.GetTypes())
  184. if (type.IsPublic)
  185. _allType.Add(type);
  186. GetAllCite();
  187. IsInheritMono = true;
  188. IsUserNamespace = true;
  189. ClassType = "类";
  190. InheritClass = "None";
  191. GetClassType();
  192. }
  193. void GetClassType()
  194. {
  195. classTypeMenu = new GenericMenu();
  196. foreach (var item in classTypeDic)
  197. {
  198. classTypeMenu.AddItem(new GUIContent(item.Key), ClassType.Equals(item.Key), () =>
  199. {
  200. ClassType = item.Key;
  201. });
  202. }
  203. }
  204. void GetAllType()
  205. {
  206. inheritClassMenu = new GenericMenu();
  207. inheritClassMenu.AddItem(new GUIContent("None"), InheritClass.Equals("None"), () => InheritClass = "None");
  208. foreach (var type in _allType)
  209. {
  210. if(ClassType=="类"&&(type.IsInterface || type.IsClass))
  211. inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName),
  212. () => InheritClass = type.FullName);
  213. else if((ClassType == "接口"|| ClassType == "结构体")&& type.IsInterface)
  214. inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName),
  215. () => InheritClass = type.FullName);
  216. else if(ClassType == "枚举"&& IntegerTypes.Contains(type))
  217. inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName),
  218. () => InheritClass = type.FullName);
  219. }
  220. }
  221. void GetAllCite()
  222. {
  223. citeMenu = new GenericMenu();
  224. foreach (var type in _allType.GroupBy(p => p.Namespace))
  225. {
  226. if (string.IsNullOrEmpty(type.Key)) continue;
  227. bool isG = Cites.Contains(type.Key);
  228. citeMenu.AddItem(new GUIContent(type.Key.Replace('.', '/')+'#'), isG , () =>
  229. {
  230. if (Cites.Contains(type.Key))
  231. Cites.Remove(type.Key);
  232. else
  233. Cites.Add(type.Key);
  234. WritScript();
  235. });
  236. }
  237. }
  238. void RefreshTemp()
  239. {
  240. selecteMenu.Clear();
  241. selecteMenu.Add("None");
  242. TempData.desTempInfos.ForEach(p =>
  243. {
  244. selecteMenu.Add(p.m_name);
  245. });
  246. }
  247. private void CreateTempData()
  248. {
  249. _tempData = ScriptableObject.CreateInstance<DesTempData>();
  250. AssetDatabase.CreateAsset(_tempData, TEMPDATAPATH);
  251. AssetDatabase.Refresh();
  252. _tempData = AssetDatabase.LoadAssetAtPath<DesTempData>(TEMPDATAPATH);
  253. }
  254. void FiedGather()
  255. {
  256. ScriptDes = string.Empty;
  257. desFiledDic.Clear();
  258. _keys.Clear();
  259. if (SelecteTemp <= 0) return;
  260. string str = TempData.desTempInfos.Find(p => p.m_name == selecteMenu[SelecteTemp]).m_des;
  261. ScriptDes = str.Replace("+", "");
  262. str = str.Remove(0,str.IndexOf("+"));
  263. str = str.Remove(str.LastIndexOf(":"));
  264. //Debug.Log(str);
  265. string[] strs = str.Split("\n");
  266. string key = string.Empty;
  267. for (int i = 0; i < strs.Length; i++)
  268. {
  269. key = string.Empty;
  270. for (int j = 0; j < strs[i].Length; j++)
  271. {
  272. if (strs[i][j] != '+'&& strs[i][j] != ':' && strs[i][j] != ':'&&strs[i][j]!=' ')
  273. key += strs[i][j];
  274. if (strs[i][j] == ':'|| strs[i][j] == ':')
  275. break;
  276. }
  277. if(!string.IsNullOrEmpty(key))
  278. {
  279. desFiledDic.Add(key, "");
  280. _keys.Add(key);
  281. }
  282. }
  283. }
  284. private void OnGUI()
  285. {
  286. using(new EditorGUILayout.HorizontalScope())
  287. {
  288. DrawLeft();
  289. DrawRight();
  290. }
  291. }
  292. void DrawLeft()
  293. {
  294. using (new EditorGUILayout.VerticalScope(GUILayout.Width(200)))
  295. {
  296. using (new EditorGUILayout.HorizontalScope())
  297. {
  298. GUILayout.Label("脚本名");
  299. ScriptName = EditorGUILayout.TextField(ScriptName);
  300. }
  301. using(new EditorGUILayout.HorizontalScope())
  302. {
  303. GUILayout.Label("脚本类型");
  304. if(GUILayout.Button(classType,EditorStyles.popup))
  305. {
  306. GetClassType();
  307. classTypeMenu.ShowAsContext();
  308. }
  309. }
  310. GUI.enabled = classType == "类";
  311. using (new EditorGUILayout.HorizontalScope())
  312. {
  313. GUILayout.Label("继承Mono");
  314. IsInheritMono = EditorGUILayout.Toggle(IsInheritMono);
  315. }
  316. GUI.enabled = true;
  317. using (new EditorGUILayout.HorizontalScope())
  318. {
  319. GUILayout.Label("脚本引用");
  320. if (GUILayout.Button("管理引用", EditorStyles.popup))
  321. {
  322. GetAllCite();
  323. citeMenu.ShowAsContext();
  324. }
  325. }
  326. if (!IsInheritMono)
  327. {
  328. using (new EditorGUILayout.HorizontalScope())
  329. {
  330. GUILayout.Label("继承父类");
  331. if (GUILayout.Button(_inheritClass, EditorStyles.popup))
  332. {
  333. GetAllType();
  334. inheritClassMenu.ShowAsContext();
  335. }
  336. }
  337. }
  338. using (new EditorGUILayout.HorizontalScope())
  339. {
  340. GUILayout.Label("使用命名空间");
  341. IsUserNamespace = EditorGUILayout.Toggle(IsUserNamespace);
  342. }
  343. if (IsUserNamespace)
  344. {
  345. using (new EditorGUILayout.HorizontalScope())
  346. {
  347. GUILayout.Label("命名空间");
  348. Namespce = EditorGUILayout.TextField(Namespce);
  349. }
  350. }
  351. using (new EditorGUILayout.HorizontalScope())
  352. {
  353. GUILayout.Label("脚本描述");
  354. SelecteTemp = EditorGUILayout.Popup(SelecteTemp,selecteMenu.ToArray());
  355. if(GUILayout.Button("新建"))
  356. {
  357. NewDesTemp.Open(TempData, RefreshTemp);
  358. }
  359. }
  360. if(_keys.Count>0)
  361. {
  362. for (int i = 0; i < _keys.Count; i++)
  363. {
  364. string value = string.Empty;
  365. int j = i;
  366. using (new EditorGUILayout.HorizontalScope())
  367. {
  368. GUILayout.Label(_keys[i],GUILayout.ExpandWidth(false));
  369. value = EditorGUILayout.TextField(desFiledDic[_keys[i]]);
  370. switch (_keys[i])
  371. {
  372. case "文件":
  373. value = ScriptName+".cs";
  374. break;
  375. case "日期":
  376. value = DateTime.Now.ToString("U");
  377. break;
  378. case "UnityVersion":
  379. case "Unity版本":
  380. value = Application.unityVersion;
  381. break;
  382. case "作者":
  383. value = User.m_name;
  384. break;
  385. case "邮箱":
  386. value = User.m_email;
  387. break;
  388. default:
  389. break;
  390. }
  391. if(value != desFiledDic[_keys[j]])
  392. {
  393. ScriptDes = ScriptDes.Replace($"?{j}{desFiledDic[_keys[j]]}", $"?{j}{value}");
  394. desFiledDic[_keys[j]] = value;
  395. }
  396. }
  397. }
  398. }
  399. GUI.color = Color.green;
  400. if (GUILayout.Button("创建"))
  401. {
  402. CreateScript();
  403. }
  404. GUI.color = Color.white;
  405. }
  406. }
  407. void DrawRight()
  408. {
  409. using (new EditorGUILayout.VerticalScope("Box"))
  410. {
  411. EditorGUILayout.LabelField("预览:");
  412. GUI.enabled = false;
  413. EditorGUILayout.TextArea(_script.ToString());
  414. GUI.enabled = true;
  415. }
  416. }
  417. private void WritScript()
  418. {
  419. _script.Clear();
  420. if (SelecteTemp > 0)
  421. {
  422. string des = ScriptDes;
  423. for (int i = 0; i < _keys.Count; i++)
  424. {
  425. des = des.Replace($"?{i}", "");
  426. }
  427. _script.Append(des);
  428. _script.Append("\n");
  429. }
  430. //if (_isInheritMonon)
  431. //{
  432. // _script.Append("using System.Collections;\n");
  433. // _script.Append("using UnityEngine;\n");
  434. //}
  435. //_script.Append("using System.Collections.Generic;\n");
  436. foreach (var item in Cites)
  437. {
  438. _script.Append($"using {item};\n");
  439. }
  440. if (_isUserNamespace)
  441. {
  442. _script.Append($"namespace {_namespce}\n");
  443. _script.Append("{\n");
  444. }
  445. _script.Append($"{(_isUserNamespace ? " " : "")}public {(classTypeDic.ContainsKey(classType)? classTypeDic[classType]:"class")} {_scriptName} {(_isInheritMonon ? ": MonoBehaviour" : (InheritClass=="None"?"":$": {InheritClass}")) }\n");
  446. _script.Append(_isUserNamespace ? " " : "");
  447. _script.Append("{\n");
  448. _script.Append(_isUserNamespace ? " " : "");
  449. _script.Append("}\n");
  450. if (_isUserNamespace)
  451. {
  452. _script.Append("}");
  453. }
  454. }
  455. private void CreateScript()
  456. {
  457. if (_script.Length < 0) return;
  458. string fullName = "Assets";
  459. UnityEngine.Object[] objects = Selection.GetFiltered<DefaultAsset>(SelectionMode.Assets);
  460. if (objects.Length > 0)
  461. fullName = AssetDatabase.GetAssetPath(objects[0]);
  462. fullName += $"/{_scriptName}.cs";
  463. string pathName = Application.dataPath.Remove(Application.dataPath.LastIndexOf("/")+1) + fullName;
  464. StreamWriter writer = new StreamWriter(pathName, false, UTF8Encoding.UTF8);
  465. writer.Write(_script.ToString());
  466. writer.Close();
  467. AssetDatabase.ImportAsset(fullName);
  468. MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(fullName);
  469. AssetDatabase.OpenAsset(script);
  470. AssetDatabase.Refresh();
  471. Close();
  472. }
  473. }
  474. public class NewDesTemp:EditorWindow
  475. {
  476. static DesTempData _tempData;
  477. static TAction onSave;
  478. DesTempInfo tempInfo = new DesTempInfo();
  479. bool isCanSave = true;
  480. public static void Open(DesTempData tempData,TAction action)
  481. {
  482. NewDesTemp win = GetWindow<NewDesTemp>();
  483. win.minSize = new Vector2(300, 300);
  484. _tempData = tempData;
  485. win.titleContent.text = "脚本描述模版";
  486. onSave = action;
  487. win.Show();
  488. }
  489. private void OnGUI()
  490. {
  491. using(new EditorGUILayout.HorizontalScope())
  492. {
  493. GUILayout.Label("名称", GUILayout.ExpandWidth(false));
  494. isCanSave = true;
  495. tempInfo.m_name = EditorGUILayout.TextField(tempInfo.m_name);
  496. if(_tempData.desTempInfos.Find(p=>p.m_name==tempInfo.m_name)!=null)
  497. {
  498. EditorGUILayout.HelpBox("存在同名模版!请更换名称", MessageType.Error);
  499. isCanSave = false;
  500. }
  501. }
  502. using (new EditorGUILayout.HorizontalScope())
  503. {
  504. GUILayout.Label("描述",GUILayout.ExpandWidth(false));
  505. tempInfo.m_des = EditorGUILayout.TextArea(tempInfo.m_des);
  506. }
  507. if(GUILayout.Button("保存"))
  508. {
  509. if(!string.IsNullOrEmpty(tempInfo.m_name)&&!string.IsNullOrEmpty(tempInfo.m_des)&&isCanSave)
  510. {
  511. _tempData.desTempInfos.Add(tempInfo);
  512. onSave?.Invoke();
  513. EditorUtility.SetDirty(_tempData);
  514. AssetDatabase.SaveAssets();
  515. Close();
  516. }
  517. }
  518. }
  519. }
  520. }