CodeGenerator.cs 5.9 KB

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