using System; using System.IO; using System.Text; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using XGame.Editor.Asset; using XGame.Framework; using XGame.Framework.ObjectCollection; namespace XGame.Editor { public abstract class CodeGenerator { /// /// 项目名字,用于确认命名空间 /// protected string productName; /// /// 脚本的根目录 /// protected string codesRootPath; protected void InitPath(string codesFolder) { var xgConfig = XGameConfig.Load(); productName = xgConfig.productName; var assemblyPath = AssetDatabase.GUIDToAssetPath(xgConfig.launchAssemblyGUID); codesRootPath = Path.Combine(Path.GetDirectoryName(assemblyPath), codesFolder); } protected bool VerifyPrefab(GameObject go) { var prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(go); if (string.IsNullOrEmpty(prefabPath)) prefabPath = PrefabStageUtility.GetCurrentPrefabStage()?.assetPath; if (string.IsNullOrEmpty(prefabPath)) { EditorUtility.DisplayDialog("Warning", $"请将该GameObject拖拽为预制体。", "确定"); return false; } var guid = AssetDatabase.AssetPathToGUID(prefabPath); string addressableName = AddressableHelper.GUIDToName(guid); if (string.IsNullOrEmpty(addressableName)) { EditorUtility.DisplayDialog("Warning", $"请点击Build/CollectAddressableAssets,以收集预制的Addressable信息。", "确定"); return false; } return true; } /// /// 通用的代码生成 /// /// /// /// /// /// /// protected bool GenCommonCode(string keyName, string componentName, string codeFileName, string templateFileName, Func customReplace = null) { var codePath = $"{codesRootPath}/{keyName}/{codeFileName}.cs"; if (File.Exists(codePath)) { EditorUtility.DisplayDialog("代码生成错误", $"存在同名脚本:{codePath}", "确认"); return false; } var dirPath = $"{codesRootPath}/{keyName}"; if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } var guids = AssetDatabase.FindAssets(templateFileName); var templatePath = AssetDatabase.GUIDToAssetPath(guids[0]); var codeText = AssetDatabase.LoadAssetAtPath(templatePath).text; codeText = codeText.Replace("<#ProductName>", productName); codeText = codeText.Replace("<#KeyName>", keyName); codeText = codeText.Replace("<#ComponentName>", componentName); if (customReplace != null) { codeText = customReplace(codeText); } File.WriteAllText(codePath, codeText, Encoding.UTF8); Debug.Log($"生成代码 Path:{codePath}"); return true; } protected bool GenViewModelCode(ObjectCollector collector, string keyName, string componentName, string vmFileName, string vmTemplateName, Func customReplace = null) { var goType = typeof(GameObject).Name; var trType = typeof(Transform).Name; var propertyDefineSb = new StringBuilder(); var propertyAssignSb = new StringBuilder(); if (collector.keys.Count > 0) { for (int i = 0; i < collector.keys.Count; i++) { var key = collector.keys[i]; var type = collector.bindTypes[i]; var propertyName = ToTitleCase(key); propertyDefineSb.AppendLine($" public {type} {propertyName} {{ get; private set; }}"); if (type == goType) { propertyAssignSb.AppendLine($" {propertyName} = collector.GetGameObject(\"{key}\");"); } else if (type == trType) { propertyAssignSb.AppendLine($" {propertyName} = collector.GetGameObject(\"{key}\").transform;"); } else { propertyAssignSb.AppendLine($" {propertyName} = collector.GetComponent<{type}>(\"{key}\");"); } } } return GenCommonCode(keyName, componentName, vmFileName, vmTemplateName, codeText => { codeText = codeText.Replace("<#PropertyDefineArea>", propertyDefineSb.ToString()); codeText = codeText.Replace("<#PropertyAssignArea>", propertyAssignSb.ToString()); if (customReplace != null) { codeText = customReplace(codeText); } return codeText; }); } /// /// 字符串首字母转大写 /// /// /// protected string ToTitleCase(string val) { //return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(val); if (string.IsNullOrEmpty(val)) { return val; } return char.ToUpper(val[0]) + val.Substring(1); } } }