using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
using System.Linq;
///
/// 配置生成器 - 用于自动生成配置管理器代码
///
public static class ConfigGenerater
{
// 常量定义
private const string ConfigsPath = "Assets/Scripts/Main/Config/Configs";
private const string ConfigManagerPath = "Assets/Scripts/Main/Config/ConfigManager.cs";
private static List ExcludeClassList = new List()
{
// 特殊表格
"InitialFunctionConfig",
"PriorLanguageConfig",
// 暂时无用的表
"PlayerFacePicStarConfig",
"PlayerFaceStarConfig",
};
[MenuItem("Tools/手动刷新")]
public static void Refresh()
{
AssetDatabase.Refresh();
}
///
/// 生成配置管理器菜单项
///
[MenuItem("Tools/生成配置管理器")]
public static void Generate()
{
try
{
// 获取所有配置类
List configClasses = GetAllConfigClasses();
if (System.IO.File.Exists(Path.Combine(Application.dataPath, "fastConfig.txt")))
{
// 如果存在 fastConfig.txt 文件,读取其中的配置类
string[] fastConfigs = System.IO.File.ReadAllLines(Path.Combine(Application.dataPath, "fastConfig.txt"));
ExcludeClassList.AddRange(fastConfigs);
}
configClasses = new List(configClasses.Where(config => !ExcludeClassList.Contains(config)));
// 生成配置管理器代码
GenerateConfigManager(configClasses);
Debug.Log($"配置管理器生成完成,共找到 {configClasses.Count} 个配置类: {string.Join(", ", configClasses)}");
// 刷新资源
AssetDatabase.Refresh();
}
catch (Exception ex)
{
Debug.LogError($"生成配置管理器时发生错误: {ex.Message}\n{ex.StackTrace}");
}
}
///
/// 获取所有配置类
///
/// 配置类名称列表
private static List GetAllConfigClasses()
{
// 获取配置目录的完整路径
string fullConfigsPath = Path.Combine(Application.dataPath, ConfigsPath.Replace("Assets/", ""));
// 检查目录是否存在
if (!Directory.Exists(fullConfigsPath))
{
Debug.LogError($"配置目录不存在: {fullConfigsPath}");
return new List();
}
try
{
List configClasses = new List();
// 获取所有C#文件
string[] files = Directory.GetFiles(fullConfigsPath, "*.cs", SearchOption.TopDirectoryOnly);
for (int i = 0; i < files.Length; i++)
{
string file = files[i];
configClasses.Add(Path.GetFileNameWithoutExtension(file));
}
return configClasses;
}
catch (Exception ex)
{
Debug.LogError($"扫描配置类时发生错误: {ex.Message}");
return new List();
}
}
///
/// 生成配置管理器代码
///
/// 配置类列表
private static void GenerateConfigManager(List configClasses)
{
// 获取配置管理器的完整路径
string fullConfigManagerPath = Path.Combine(Application.dataPath, ConfigManagerPath.Replace("Assets/", ""));
try
{
// 生成完整的配置管理器代码
string configManagerCode = GenerateFullConfigManagerCode(configClasses);
// 写入文件
File.WriteAllText(fullConfigManagerPath, configManagerCode);
Debug.Log($"成功生成配置管理器: {fullConfigManagerPath}");
}
catch (Exception ex)
{
Debug.LogError($"生成配置管理器文件时发生错误: {ex.Message}");
}
}
///
/// 生成完整的配置管理器代码
///
/// 配置类列表
/// 完整的配置管理器代码
private static string GenerateFullConfigManagerCode(List configClasses)
{
StringBuilder sb = new StringBuilder();
// 头部命名空间
sb.AppendLine("using System;");
sb.AppendLine("using System.Collections.Generic;");
sb.AppendLine("using UnityEngine;");
sb.AppendLine("using Cysharp.Threading.Tasks;");
sb.AppendLine("using System.Reflection;");
sb.AppendLine();
sb.AppendLine();
sb.AppendLine("public class ConfigManager : ManagerBase");
sb.AppendLine("{");
sb.AppendLine(" public bool isLoadFinished");
sb.AppendLine(" {");
sb.AppendLine(" get;");
sb.AppendLine(" private set;");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" private float loadingProgress = 0f;");
sb.AppendLine();
sb.AppendLine(" public override void Init()");
sb.AppendLine(" {");
sb.AppendLine(" base.Init();");
sb.AppendLine(" InitConfigs();");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" public virtual async UniTask InitConfigs()");
sb.AppendLine(" {");
sb.AppendLine(" // 加载配置文件");
sb.AppendLine(" await LoadConfigs();");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" protected async UniTask LoadConfigs()");
sb.AppendLine(" {");
sb.AppendLine(" loadingProgress = 0f;");
sb.AppendLine(" isLoadFinished = false;");
sb.AppendLine();
sb.AppendLine(" // 加载配置文件");
sb.AppendLine($" int totalConfigs = {configClasses.Count};");
sb.AppendLine(" List configTypes = new List() {");
for (int i = 0; i < configClasses.Count; i++)
{
sb.Append($" typeof({configClasses[i]})");
sb.AppendLine(i < configClasses.Count - 1 ? "," : "");
}
sb.AppendLine(" };");
sb.AppendLine();
sb.AppendLine("#if UNITY_EDITOR");
sb.AppendLine(" HashSet configHashSet = new HashSet();");
sb.AppendLine(" if (System.IO.File.Exists(Application.dataPath + \"/fastConfig.txt\"))");
sb.AppendLine(" {");
sb.AppendLine(" string[] strConfgsArr = System.IO.File.ReadAllLines(Application.dataPath + \"/fastConfig.txt\");");
sb.AppendLine(" foreach (string str in strConfgsArr)");
sb.AppendLine(" {");
sb.AppendLine(" Type tpy = Type.GetType(str);");
sb.AppendLine(" configHashSet.Add(tpy);");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine(" // 编辑器下加入 评估加载时常");
sb.AppendLine(" configTypes.AddRange(configHashSet);");
sb.AppendLine(" List fastName = new List();");
sb.AppendLine("#endif");
sb.AppendLine(" // 逐个加载配置并更新进度");
sb.AppendLine(" for (int i = 0; i < configTypes.Count; i++)");
sb.AppendLine(" {");
sb.AppendLine(" var sw = System.Diagnostics.Stopwatch.StartNew();");
sb.AppendLine(" LoadConfigByType(configTypes[i]);");
sb.AppendLine(" sw.Stop();");
sb.AppendLine("#if UNITY_EDITOR");
sb.AppendLine(" if (sw.ElapsedMilliseconds >= 100)");
sb.AppendLine(" {");
sb.AppendLine(" Debug.LogError($\"加载配置 {configTypes[i].Name} 耗时较长: {sw.ElapsedMilliseconds} ms\");");
sb.AppendLine(" }");
sb.AppendLine(" else if (sw.ElapsedMilliseconds <= 5)");
sb.AppendLine(" {");
sb.AppendLine(" fastName.Add(configTypes[i].Name);");
sb.AppendLine(" }");
sb.AppendLine(" Debug.Log($\"加载配置: {configTypes[i].Name} 用时: {sw.ElapsedMilliseconds} ms\");");
sb.AppendLine("#endif");
sb.AppendLine(" loadingProgress = (float)(i + 1) / totalConfigs;");
sb.AppendLine(" }");
sb.AppendLine("#if UNITY_EDITOR");
sb.AppendLine(" System.IO.File.WriteAllText(Application.dataPath + \"/fastConfig.txt\", string.Join(\"\\n\", fastName));");
sb.AppendLine();
sb.AppendLine(" //加载完后卸载");
sb.AppendLine(" foreach (var configType in configTypes)");
sb.AppendLine(" {");
sb.AppendLine(" var methodInfo = configType.GetMethod(\"ForceRelease\", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);");
sb.AppendLine(" if (methodInfo != null)");
sb.AppendLine(" {");
sb.AppendLine(" methodInfo.Invoke(null, null);");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine("#endif");
sb.AppendLine();
sb.AppendLine(" // 加载完成后设置isLoadFinished为true");
sb.AppendLine(" loadingProgress = 1f;");
sb.AppendLine(" isLoadFinished = true;");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" public void LoadConfigByType(Type configType)");
sb.AppendLine(" {");
sb.AppendLine(" string configName = configType.Name;");
sb.AppendLine(" if (configName.EndsWith(\"Config\"))");
sb.AppendLine(" {");
sb.AppendLine(" configName = configName.Substring(0, configName.Length - 6);");
sb.AppendLine(" }");
sb.AppendLine(" string[] texts = ResManager.Instance.LoadConfig(configName);");
sb.AppendLine(" if (texts != null)");
sb.AppendLine(" {");
sb.AppendLine(" string[] lines = texts;");
sb.AppendLine(" var methodInfo = configType.GetMethod(\"Init\", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);");
sb.AppendLine(" if (methodInfo != null)");
sb.AppendLine(" {");
sb.AppendLine(" methodInfo.Invoke(null, new object[] { lines });");
sb.AppendLine(" // 设置初始化标志");
sb.AppendLine(" var isInitField = configType.GetField(\"isInit\", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);");
sb.AppendLine(" if (isInitField != null)");
sb.AppendLine(" {");
sb.AppendLine(" isInitField.SetValue(null, true);");
sb.AppendLine(" }");
sb.AppendLine(" Debug.Log($\"加载配置: {configType.Name} 成功\");");
sb.AppendLine(" }");
sb.AppendLine(" else");
sb.AppendLine(" {");
sb.AppendLine(" Debug.LogError($\"配置类 {configType.Name} 没有静态Init方法\");");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine(" else");
sb.AppendLine(" {");
sb.AppendLine(" Debug.LogError($\"找不到配置文件: {configName}\");");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" private async UniTask LoadConfig() where T : class");
sb.AppendLine(" {");
sb.AppendLine(" string configName = typeof(T).Name;");
sb.AppendLine();
sb.AppendLine(" string[] texts = ResManager.Instance.LoadConfig(configName);");
sb.AppendLine(" if (texts != null)");
sb.AppendLine(" {");
sb.AppendLine(" string[] lines = texts;");
sb.AppendLine(" var methodInfo = typeof(T).GetMethod(\"Init\", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);");
sb.AppendLine(" if (methodInfo != null)");
sb.AppendLine(" {");
sb.AppendLine(" methodInfo.Invoke(null, lines);");
sb.AppendLine(" // 设置初始化标志");
sb.AppendLine(" var isInitField = typeof(T).GetField(\"isInit\", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);");
sb.AppendLine(" if (isInitField != null)");
sb.AppendLine(" {");
sb.AppendLine(" isInitField.SetValue(null, true);");
sb.AppendLine(" }");
sb.AppendLine(" Debug.Log($\"加载配置: {typeof(T).Name} 成功\");");
sb.AppendLine(" }");
sb.AppendLine(" else");
sb.AppendLine(" {");
sb.AppendLine(" Debug.LogError($\"配置类 {typeof(T).Name} 没有静态Init方法\");");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine(" else");
sb.AppendLine(" {");
sb.AppendLine(" Debug.LogError($\"找不到配置文件: {configName}\");");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" public float GetLoadingProgress()");
sb.AppendLine(" {");
sb.AppendLine(" return loadingProgress;");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" private void ClearConfigDictionary() where T : class");
sb.AppendLine(" {");
sb.AppendLine(" // 重置 T 初始化状态");
sb.AppendLine(" var isInitField = typeof(T).GetField(\"isInit\", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);");
sb.AppendLine(" if (isInitField != null)");
sb.AppendLine(" {");
sb.AppendLine(" isInitField.SetValue(null, false);");
sb.AppendLine(" }");
sb.AppendLine(" }");
sb.AppendLine();
sb.AppendLine(" public override void Release()");
sb.AppendLine(" {");
foreach (string className in configClasses)
{
sb.AppendLine($" // 清空 {className} 字典");
sb.AppendLine($" ClearConfigDictionary<{className}>();");
}
sb.AppendLine(" }");
sb.AppendLine("}");
return sb.ToString();
}
}