using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using UnityEditor; using UnityEngine; /// /// 配置生成器 - 用于自动生成配置管理器代码 /// public static class ConfigGenerater { // 常量定义 private const string ResourcesOutConfigPath = "Assets/ResourcesOut/Config"; private const string ConfigClassesPath = "Assets/Scripts/Main/Config/Configs"; private const string ConfigManagerPath = "Assets/Scripts/Main/Config/ConfigManager.cs"; public static List ExcludeClassList = new List() { // 特殊表格(由 preInitConfig 单独加载,不进入 configTypes) // "InitialFunctionConfig", // "PriorLanguageConfig", // "FuncConfigConfig", // 暂时无用的表 "PlayerFacePicStarConfig", "PlayerFaceStarConfig", }; [MenuItem("Tools/手动刷新")] public static void Refresh() { AssetDatabase.Refresh(); } /// /// 生成配置管理器菜单项 /// [MenuItem("Tools/生成配置管理器")] public static void Generate() { try { // 1. 获取所有配置类(去除排除项) List configClasses = GetAllConfigClasses() .Where(c => !ExcludeClassList.Contains(c)) .Where(c => !string.IsNullOrEmpty(c) && char.IsUpper(c[0])) .ToList(); string configManagerPath = Path.Combine(Application.dataPath, ConfigManagerPath.Replace("Assets/", "")); var lines = File.ReadAllLines(configManagerPath).ToList(); // --- 更新 configTypes HashSet --- int loadConfigsIdx = lines.FindIndex(l => l.Contains("protected async UniTask LoadConfigs()")); if (loadConfigsIdx < 0) { Debug.LogError("未找到 'protected async UniTask LoadConfigs()',请检查 ConfigManager.cs 结构。"); return; } var configTypeLines = new List(); configTypeLines.Add(" // 加载配置文件"); configTypeLines.Add(" HashSet configTypes = new HashSet() {"); for (int i = 0; i < configClasses.Count; i++) { configTypeLines.Add($" typeof({configClasses[i]}){(i < configClasses.Count - 1 ? "," : "")}"); } configTypeLines.Add(" };"); int configTypesStart = lines.FindIndex(loadConfigsIdx, l => l.Contains("HashSet configTypes")); int configTypesEnd = configTypesStart; while (configTypesEnd < lines.Count && !lines[configTypesEnd].Trim().EndsWith("};")) configTypesEnd++; configTypesEnd++; lines.RemoveRange(configTypesStart, configTypesEnd - configTypesStart); lines.InsertRange(configTypesStart, configTypeLines); // --- 更新 Release() 方法体 --- int releaseIdx = lines.FindIndex(l => l.TrimStart().StartsWith("public override void Release()")); if (releaseIdx >= 0) { int releaseOpen = lines.FindIndex(releaseIdx, l => l.Trim() == "{"); int releaseClose = releaseOpen; int braceCount = 1; for (int i = releaseOpen + 1; i < lines.Count; i++) { foreach (char ch in lines[i]) { if (ch == '{') braceCount++; if (ch == '}') braceCount--; } if (braceCount == 0) { releaseClose = i; break; } } var releaseLines = new List(); foreach (string className in configClasses) { releaseLines.Add($" // 清空 {className} 字典"); releaseLines.Add($" ClearConfigDictionary<{className}>();"); } lines.RemoveRange(releaseOpen + 1, releaseClose - releaseOpen - 1); lines.InsertRange(releaseOpen + 1, releaseLines); } // 保存文件 File.WriteAllLines(configManagerPath, lines); Debug.Log($"ConfigManager.cs 自动生成成功,共 {configClasses.Count} 个类型。"); AssetDatabase.Refresh(); } catch (Exception ex) { Debug.LogError($"自动生成 ConfigManager 时发生错误: {ex.Message}\n{ex.StackTrace}"); } } /// /// 获取所有配置类 /// /// 配置类名称列表 public static List GetAllConfigClasses() { // 以 ResourcesOut/Config 为权威来源,扫描 .txt 文件生成类名 string fullResPath = Path.Combine(Application.dataPath, ResourcesOutConfigPath.Replace("Assets/", "")); string fullCsPath = Path.Combine(Application.dataPath, ConfigClassesPath.Replace("Assets/", "")); if (!Directory.Exists(fullResPath)) { Debug.LogError($"ResourcesOut/Config 目录不存在: {fullResPath}"); return new List(); } try { List configClasses = new List(); // 扫描 ResourcesOut/Config 下的 .txt 文件,构造类名 = 文件名 + "Config" string[] txtFiles = Directory.GetFiles(fullResPath, "*.txt", SearchOption.TopDirectoryOnly); foreach (string file in txtFiles) { string baseName = Path.GetFileNameWithoutExtension(file); string className = baseName + "Config"; // 交叉验证:对应的 C# 类文件必须存在 string csFile = Path.Combine(fullCsPath, className + ".cs"); if (!File.Exists(csFile)) continue; configClasses.Add(className); } return configClasses; } catch (Exception ex) { Debug.LogError($"扫描配置类时发生错误: {ex.Message}"); return new List(); } } }