LabelUtility.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. using System.Reflection;
  2. namespace labelUtility
  3. {
  4. #if UNITY_EDITOR
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Xml;
  13. using UnityEditor;
  14. using UnityEngine;
  15. using UnityEngine.UI;
  16. [Serializable]
  17. public class LabelSet //todo 更新
  18. {
  19. public string Name;
  20. public string LabelScriptPath;
  21. public string LabelScriptName;
  22. public string LabePrefix = "public static string";
  23. public TextAsset LabelScript;
  24. public string ComponentScriptPath;
  25. public string ComponentScriptName;
  26. public string ComponentPrefix = "private";
  27. public string NameExcludeString;
  28. //public string RegistPrefix;
  29. //public string RegistSuffix;
  30. public string RegistString;
  31. public List<string> RegistExtraLines;
  32. public TextAsset ComponentScript;
  33. public List<TextAsset> Languages; //todo 需要更新为LanguageXml
  34. public List<GameObject> Prefabs;
  35. public bool FoldOut;
  36. public float TotalHeight;
  37. public List<ComponentPurview> ComponentPurviews = new List<ComponentPurview>();
  38. }
  39. public enum ComponentPurview //todo 更新
  40. {
  41. Text,
  42. Slider,
  43. Image,
  44. Button,
  45. InputField,
  46. Transform,
  47. RectTransform,
  48. SpriteRenderer,
  49. VirtualScrollRectPlus,
  50. }
  51. public class LabelUtility : MonoBehaviour
  52. {
  53. #region Config
  54. public List<LabelSet> LabelSets;
  55. public static string StartMark = "//StartMark-Used by LabelUtility-Do not remove"; //todo 更新
  56. public static string EndMark = "//EndMark-Used by LabelUtility-Do not remove"; //todo 更新
  57. public static string RegistStartMark = "//RegistStartMark-Used by LabelUtility-Do not remove"; //todo 更新
  58. public static string RegistEndMark = "//RegistEndMark-Used by LabelUtility-Do not remove"; //todo 更新
  59. public static string Prefix = "public static string ";
  60. #endregion
  61. public static void CreateLabelScript(LabelSet labelSet)
  62. {
  63. if (!EditorUtility.DisplayDialog("注意", "新建LabelScript?", "确定", "取消"))
  64. {
  65. return;
  66. }
  67. labelSet.LabelScript = CreateScript(labelSet.LabelScriptName, labelSet.LabelScriptPath);
  68. }
  69. public static void CreateComponentScript(LabelSet labelSet)
  70. {
  71. if (!EditorUtility.DisplayDialog("注意", "新建ComponentScript?", "确定", "取消"))
  72. {
  73. return;
  74. }
  75. labelSet.ComponentScript = CreateScript(labelSet.ComponentScriptName, labelSet.ComponentScriptPath);
  76. }
  77. private static TextAsset CreateScript(string scriptName, string scriptPath)
  78. {
  79. string directory = scriptPath.TrimEnd('/', '\\') + "/";
  80. if (directory.Length < 6 || directory.Substring(0, 6).ToLower() != "assets")
  81. {
  82. throw new Exception("ScripPath必须位置Assets目录内");
  83. }
  84. if (!Directory.Exists(directory))
  85. {
  86. throw new Exception("文件夹不存在");
  87. }
  88. if (string.IsNullOrEmpty(scriptName) || scriptName.Any(Path.GetInvalidFileNameChars().Contains))
  89. {
  90. throw new Exception("ScripName包含无效字符");
  91. }
  92. string fullPath = $"{scriptPath}/{scriptName}.cs";
  93. if (File.Exists(fullPath))
  94. {
  95. throw new Exception($"已经存在一个 {fullPath}");
  96. }
  97. string scriptContent = $"public class {scriptName}\r\n{{\r\n\t#region Config\r\n\r\n\t{StartMark}\r\n\t{EndMark}\r\n\r\n\t#endregion\r\n}}";
  98. File.WriteAllText(fullPath, scriptContent);
  99. AssetDatabase.Refresh();
  100. return AssetDatabase.LoadAssetAtPath<TextAsset>(fullPath);
  101. }
  102. public static void CreateLabelFromPrefab(LabelSet labelSet) //todo 更新
  103. {
  104. if (!EditorUtility.DisplayDialog("注意", "重新生成Prefab Label?", "确定", "取消"))
  105. {
  106. return;
  107. }
  108. List<string> labels = new List<string>();
  109. List<Transform> transforms = GetAllTransformFromPrefab(labelSet.Prefabs);
  110. foreach (var transform in transforms)
  111. {
  112. labels.Add($"{labelSet.LabePrefix} {transform.name} = \"{transform.name}\";");
  113. }
  114. InsertLineToScript(StartMark, EndMark, labelSet.LabelScript, labels);
  115. }
  116. public static void CreateLabelFromLanguageXml(LabelSet labelSet) //todo 更新
  117. {
  118. if (!EditorUtility.DisplayDialog("注意", "重新生成LanguageXml Label?", "确定", "取消"))
  119. {
  120. return;
  121. }
  122. List<string> labels = new List<string>();
  123. foreach (var language in labelSet.Languages)
  124. {
  125. XmlDocument document = new XmlDocument();
  126. document.LoadXml(language.text);
  127. XmlNodeList childNodes = document.SelectSingleNode("lan").ChildNodes;
  128. for (int i = 0; i < childNodes.Count; i++)
  129. {
  130. labels.AddRange(GetAllLabelFromXmlNode(childNodes[i], labelSet));
  131. }
  132. }
  133. InsertLineToScript(StartMark, EndMark, labelSet.LabelScript, labels);
  134. }
  135. private static List<string> GetAllLabelFromXmlNode(XmlNode node, LabelSet labelSet) //todo 增加
  136. {
  137. List<string> labels = new List<string>();
  138. for (int i = 0; i < node.ChildNodes.Count; i++)
  139. {
  140. XmlNode childNode = node.ChildNodes[i];
  141. string label;
  142. if (i == 0)
  143. {
  144. label = $"\t{labelSet.LabePrefix} {node.Name} = \"{node.Name}\";";
  145. labels.Add(label);
  146. }
  147. label = $"\t{labelSet.LabePrefix} {node.Name}{LanguageLabel.LanguagePageSeperator}{childNode.Name} = \"{node.Name}{LanguageLabel.LanguagePageSeperator}{childNode.Name}\";";
  148. labels.Add(label);
  149. }
  150. return labels;
  151. }
  152. public static void CreateComponentsFromPrefab(LabelSet labelSet) //todo 更新
  153. {
  154. if (!EditorUtility.DisplayDialog("注意", "重新生成PrefabComponent?", "确定", "取消"))
  155. {
  156. return;
  157. }
  158. List <string> typeNames = new List<string>();
  159. foreach (var purview in labelSet.ComponentPurviews)
  160. {
  161. typeNames.Add(purview.ToString());
  162. }
  163. List <Transform> transforms = GetAllTransformFromPrefab(labelSet.Prefabs);
  164. Dictionary<string, List<string>> namesDictionary = new Dictionary<string, List<string>>();
  165. foreach (var name in typeNames)
  166. {
  167. namesDictionary.Add(name, new List<string>());
  168. }
  169. foreach (var kv in namesDictionary)
  170. {
  171. Assembly assembly = Assembly.Load("UnityEngine.UI");
  172. Type type = assembly.GetType($"UnityEngine.UI.{kv.Key}");
  173. //Debug.Log($"UnityEngine.UI.{kv.Key}");
  174. if (type == null)
  175. {
  176. assembly = Assembly.Load("UnityEngine");
  177. type = assembly.GetType($"UnityEngine.{kv.Key}");
  178. }
  179. if (type == null)
  180. {
  181. assembly = Assembly.Load("Assembly-CSharp");
  182. type = assembly.GetType($"{kv.Key}");
  183. }
  184. foreach (var transform in transforms)
  185. {
  186. if (transform.GetComponent(type) == null) continue;
  187. namesDictionary[kv.Key].Add(transform.name);
  188. }
  189. }
  190. List<string> names = new List<string>();
  191. List<string> components = new List<string>();
  192. List<string> registStrings = new List<string>();
  193. registStrings.AddRange(labelSet.RegistExtraLines);
  194. foreach (var kv in namesDictionary)
  195. {
  196. foreach (var name in kv.Value)
  197. {
  198. names.Add(name);
  199. string newName = string.IsNullOrEmpty(labelSet.NameExcludeString) ? name : name.Replace(labelSet.NameExcludeString, "");
  200. components.Add($"{labelSet.ComponentPrefix} {kv.Key} {newName};");
  201. registStrings.Add(labelSet.RegistString.Replace("#NAME", name).Replace("#TYPE", kv.Key).Replace("#NEWNAME", newName));
  202. }
  203. }
  204. //for (int i = 0; i < names.Count; i++)
  205. //{
  206. // components.Add(names[i].Substring(names[i].IndexOf(' ') + 1));
  207. //}
  208. InsertLineToScript(StartMark, EndMark, labelSet.ComponentScript, components);
  209. InsertLineToScript(RegistStartMark, RegistEndMark, labelSet.ComponentScript, registStrings);
  210. //List<string> names = new List<string>();
  211. //List<string> textNames = new List<string>();
  212. //List<string> sliderNames = new List<string>();
  213. //List<string> imageNames = new List<string>();
  214. //List<string> buttonNames = new List<string>();
  215. //List<string> transformNames = new List<string>();
  216. //List<string> rectTransformNames = new List<string>();
  217. //List<string> spriteRendererNames = new List<string>();
  218. //List<Transform> transforms = GetAllTransformFromPrefab(labelSet.Prefabs);
  219. //foreach (var transform in transforms)
  220. //{
  221. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.Text) && transform.GetComponent<Text>() != null)
  222. // {
  223. // textNames.Add($"Text {transform.name}");
  224. // }
  225. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.Slider) && transform.GetComponent<Slider>() != null)
  226. // {
  227. // sliderNames.Add($"Slider {transform.name}");
  228. // }
  229. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.Image) && transform.GetComponent<Image>() != null)
  230. // {
  231. // sliderNames.Add($"Image {transform.name}");
  232. // }
  233. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.Button) && transform.GetComponent<Button>() != null)
  234. // {
  235. // buttonNames.Add($"Button {transform.name}");
  236. // }
  237. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.Transform) && transform.GetComponent<Transform>() != null)
  238. // {
  239. // transformNames.Add($"Transform {transform.name}");
  240. // }
  241. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.RectTransform) && transform.GetComponent<RectTransform>() != null)
  242. // {
  243. // rectTransformNames.Add($"RectTransform {transform.name}");
  244. // }
  245. // if (labelSet.ComponentPurviews.Contains(ComponentPurview.SpriteRenderer) && transform.GetComponent<SpriteRenderer>() != null)
  246. // {
  247. // spriteRendererNames.Add($"SpriteRenderer {transform.name}");
  248. // }
  249. //}
  250. //names.AddRange(textNames);
  251. //names.AddRange(sliderNames);
  252. //names.AddRange(imageNames);
  253. //names.AddRange(buttonNames);
  254. //names.AddRange(transformNames);
  255. //names.AddRange(rectTransformNames);
  256. //names.AddRange(spriteRendererNames);
  257. //List<string> components = new List<string>();
  258. //for (int i = 0; i < names.Count; i++)
  259. //{
  260. // string name = string.IsNullOrEmpty(labelSet.NameExcludeString) ? names[i] : names[i].Replace(labelSet.NameExcludeString, "");
  261. // components.Add($"{labelSet.ComponentPrefix} {name};");
  262. //}
  263. //for (int i = 0; i < names.Count; i++)
  264. //{
  265. // components.Add(names[i].Substring(names[i].IndexOf(' ') + 1));
  266. //}
  267. //InsertLineToScript(labelSet.ComponentScript, components);
  268. }
  269. private static void InsertLineToScript(string startMark, string endMark, TextAsset textAsset, List<string> insertLines)
  270. {
  271. int? startMarkLineIndex = null;
  272. int? endMarkLineIndex = null;
  273. List<string> strings = GetScriptContentAfterClearMarks(startMark, endMark, textAsset, ref startMarkLineIndex, ref endMarkLineIndex);
  274. int prefixIndex = strings[startMarkLineIndex.Value].IndexOf("//");
  275. string prefix = strings[startMarkLineIndex.Value].Substring(0, prefixIndex);
  276. for (int i = 0; i < insertLines.Count; i++)
  277. {
  278. strings.Insert(startMarkLineIndex.Value + 1, prefix + insertLines[i]);
  279. startMarkLineIndex++;
  280. }
  281. StringBuilder stringBuilder = new StringBuilder();
  282. for (int i = 0; i < strings.Count; i++)
  283. {
  284. stringBuilder.AppendLine(strings[i]);
  285. }
  286. string content = stringBuilder.ToString();
  287. content = content.Substring(0, content.Length - 2);
  288. File.WriteAllText(AssetDatabase.GetAssetPath(textAsset), content);
  289. AssetDatabase.Refresh();
  290. }
  291. private static List<string> GetScriptContentAfterClearMarks(string startMark, string endMark, TextAsset textAsset, ref int? startMarkLineIndex, ref int? endMarkLineIndex)
  292. {
  293. List<string> strings = textAsset.text.Split(new[] {"\r\n"}, StringSplitOptions.None).ToList();
  294. //List<string> currentDefinedNames = new List<string>();
  295. for (int i = 0; i < strings.Count; i++)
  296. {
  297. if (strings[i].Contains(startMark))
  298. {
  299. startMarkLineIndex = i;
  300. }
  301. else if (strings[i].Contains(endMark))
  302. {
  303. endMarkLineIndex = i;
  304. }
  305. //if (startMarkLineIndex != null)
  306. //{
  307. // if (endMarkLineIndex != null)
  308. // {
  309. // if (i > startMarkLineIndex.Value && i < endMarkLineIndex.Value)
  310. // {
  311. // currentDefinedNames.Add(GetDefinedName(strings[i]));
  312. // }
  313. // }
  314. // else
  315. // {
  316. // if (i > startMarkLineIndex.Value)
  317. // {
  318. // currentDefinedNames.Add(GetDefinedName(strings[i]));
  319. // }
  320. // }
  321. //}
  322. }
  323. int definedCount = endMarkLineIndex.Value - startMarkLineIndex.Value - 1;
  324. for (int i = 0; i < definedCount; i++)
  325. {
  326. strings.RemoveAt(startMarkLineIndex.Value + 1);
  327. }
  328. return strings;
  329. }
  330. private static List<Transform> GetAllTransformFromPrefab(List<GameObject> prefabs)
  331. {
  332. List<Transform> transforms = new List<Transform>();
  333. for (int i = 0; i < prefabs.Count; i++)
  334. {
  335. transforms.AddRange(prefabs[i].GetComponentsInChildren<Transform>(true));
  336. }
  337. return transforms;
  338. }
  339. }
  340. #endif
  341. }