CodeGenerator.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using UnityEditor;
  5. using UnityEditor.SceneManagement;
  6. using UnityEngine;
  7. using XGame.Editor.Asset;
  8. using XGame.Framework;
  9. using XGame.Framework.ObjectCollection;
  10. namespace XGame.Editor
  11. {
  12. public abstract class CodeGenerator
  13. {
  14. /// <summary>
  15. /// 项目名字,用于确认命名空间
  16. /// </summary>
  17. protected string productName;
  18. /// <summary>
  19. /// 脚本的根目录
  20. /// </summary>
  21. protected string codesRootPath;
  22. protected void InitPath(string codesFolder)
  23. {
  24. var xgConfig = AddressableHelper.LoadAssetByName<XGameConfig>(Framework.Define.AssetDefine.XGAME_CONFIG_NAME);
  25. productName = xgConfig.productName;
  26. var assemblyPath = AssetDatabase.GUIDToAssetPath(xgConfig.launchAssemblyGUID);
  27. codesRootPath = Path.Combine(Path.GetDirectoryName(assemblyPath), codesFolder);
  28. }
  29. protected bool VerifyPrefab(GameObject go)
  30. {
  31. var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(go);
  32. if (string.IsNullOrEmpty(prefabPath))
  33. prefabPath = PrefabStageUtility.GetCurrentPrefabStage()?.assetPath;
  34. if (string.IsNullOrEmpty(prefabPath))
  35. {
  36. EditorUtility.DisplayDialog("Warning", $"请将该GameObject拖拽为预制体。", "确定");
  37. return false;
  38. }
  39. var guid = AssetDatabase.AssetPathToGUID(prefabPath);
  40. string addressableName = AddressableHelper.GUIDToName(guid);
  41. if (string.IsNullOrEmpty(addressableName))
  42. {
  43. EditorUtility.DisplayDialog("Warning", $"请点击Build/CollectAddressableAssets,以收集预制的Addressable信息。", "确定");
  44. return false;
  45. }
  46. return true;
  47. }
  48. /// <summary>
  49. /// 通用的代码生成
  50. /// </summary>
  51. /// <param name="keyName"></param>
  52. /// <param name="componentName"></param>
  53. /// <param name="codeFileName"></param>
  54. /// <param name="templateFileName"></param>
  55. /// <param name="customReplace"></param>
  56. /// <returns></returns>
  57. protected bool GenCommonCode(string keyName, string componentName, string codeFileName, string templateFileName, Func<string, string> customReplace = null)
  58. {
  59. var codePath = $"{codesRootPath}/{keyName}/{codeFileName}.cs";
  60. if (File.Exists(codePath))
  61. {
  62. EditorUtility.DisplayDialog("代码生成错误", $"存在同名脚本:{codePath}", "确认");
  63. return false;
  64. }
  65. var dirPath = $"{codesRootPath}/{keyName}";
  66. if (!Directory.Exists(dirPath))
  67. {
  68. Directory.CreateDirectory(dirPath);
  69. }
  70. var guids = AssetDatabase.FindAssets(templateFileName);
  71. var templatePath = AssetDatabase.GUIDToAssetPath(guids[0]);
  72. var codeText = AssetDatabase.LoadAssetAtPath<TextAsset>(templatePath).text;
  73. codeText = codeText.Replace("<#ProductName>", productName);
  74. codeText = codeText.Replace("<#KeyName>", keyName);
  75. codeText = codeText.Replace("<#ComponentName>", componentName);
  76. if (customReplace != null)
  77. {
  78. codeText = customReplace(codeText);
  79. }
  80. File.WriteAllText(codePath, codeText, Encoding.UTF8);
  81. Debug.Log($"生成代码 Path:{codePath}");
  82. return true;
  83. }
  84. protected bool GenViewModelCode(ObjectCollector collector, string keyName, string componentName, string vmFileName, string vmTemplateName, Func<string, string> customReplace = null)
  85. {
  86. var goType = typeof(GameObject).Name;
  87. var trType = typeof(Transform).Name;
  88. var propertyDefineSb = new StringBuilder();
  89. var propertyAssignSb = new StringBuilder();
  90. if (collector.keys.Count > 0)
  91. {
  92. for (int i = 0; i < collector.keys.Count; i++)
  93. {
  94. var key = collector.keys[i];
  95. var type = collector.bindTypes[i];
  96. var propertyName = ToTitleCase(key);
  97. propertyDefineSb.AppendLine($" public {type} {propertyName} {{ get; private set; }}");
  98. if (type == goType)
  99. {
  100. propertyAssignSb.AppendLine($" {propertyName} = collector.GetGameObject(\"{key}\");");
  101. }
  102. else if (type == trType)
  103. {
  104. propertyAssignSb.AppendLine($" {propertyName} = collector.GetGameObject(\"{key}\").transform;");
  105. }
  106. else
  107. {
  108. propertyAssignSb.AppendLine($" {propertyName} = collector.GetComponent<{type}>(\"{key}\");");
  109. }
  110. }
  111. }
  112. return GenCommonCode(keyName, componentName, vmFileName, vmTemplateName, codeText =>
  113. {
  114. codeText = codeText.Replace("<#PropertyDefineArea>", propertyDefineSb.ToString());
  115. codeText = codeText.Replace("<#PropertyAssignArea>", propertyAssignSb.ToString());
  116. if (customReplace != null)
  117. {
  118. codeText = customReplace(codeText);
  119. }
  120. return codeText;
  121. });
  122. }
  123. /// <summary>
  124. /// 字符串首字母转大写
  125. /// </summary>
  126. /// <param name="val"></param>
  127. /// <returns></returns>
  128. protected string ToTitleCase(string val)
  129. {
  130. //return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(val);
  131. if (string.IsNullOrEmpty(val))
  132. {
  133. return val;
  134. }
  135. return char.ToUpper(val[0]) + val.Substring(1);
  136. }
  137. }
  138. }