using System;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using Cysharp.Threading.Tasks;
|
using System.Reflection;
|
using System.Linq;
|
|
#if UNITY_EDITOR
|
using UnityEditor;
|
#endif
|
|
public class ConfigManager : ManagerBase<ConfigManager>
|
{
|
public bool isLoadFinished
|
{
|
get;
|
private set;
|
}
|
|
private float loadingProgress = 0f;
|
|
public override void Init()
|
{
|
base.Init();
|
InitConfigs();
|
}
|
|
public virtual async UniTask InitConfigs()
|
{
|
// 加载配置文件
|
await LoadConfigs();
|
}
|
|
protected async UniTask LoadConfigs()
|
{
|
loadingProgress = 0f;
|
isLoadFinished = false;
|
|
// 加载配置文件
|
HashSet<Type> configTypes = new HashSet<Type>() {
|
typeof(ChestsAwardConfig),
|
typeof(CTGConfig),
|
typeof(DamageNumConfig),
|
typeof(DirtyWordConfig),
|
typeof(FaceConfig),
|
typeof(HeroLineupHaloConfig),
|
typeof(HeroQualityLVConfig),
|
typeof(ItemConfig),
|
typeof(MainChapterConfig),
|
typeof(MainLevelConfig),
|
typeof(NPCConfig),
|
typeof(NPCExConfig),
|
typeof(NPCLineupConfig),
|
typeof(OrderInfoConfig),
|
typeof(PlayerAttrConfig),
|
typeof(PlayerFaceConfig),
|
typeof(StoreConfig),
|
typeof(SuccessConfig),
|
typeof(SysInfoConfig),
|
typeof(TitleStarUpConfig),
|
typeof(TreasureSetConfig),
|
typeof(TreeLVConfig),
|
typeof(WindowSearchConfig),
|
typeof(XBGetItemConfig)
|
};
|
|
#if UNITY_EDITOR
|
HashSet<Type> configHashSet = new HashSet<Type>();
|
if (System.IO.File.Exists(Application.dataPath + "/fastConfig.txt") && Launch.Instance.isOpenConfigTesting)
|
{
|
string[] strConfgsArr = System.IO.File.ReadAllLines(Application.dataPath + "/fastConfig.txt");
|
foreach (string str in strConfgsArr)
|
{
|
Type tpy = Type.GetType(str);
|
configHashSet.Add(tpy);
|
}
|
}
|
// 编辑器下加入 评估加载时常
|
foreach (var config in configHashSet)
|
{
|
if (!configTypes.Add(config))
|
{
|
Debug.LogWarning($"配置 {config.Name} 已经存在于 configTypes 中,跳过添加。");
|
}
|
}
|
List<string> fastName = new List<string>();
|
#endif
|
int iterator = 0;
|
int totalConfigs = configTypes.Count;
|
|
// 逐个加载配置并更新进度
|
foreach (var configType in configTypes)
|
{
|
var sw = System.Diagnostics.Stopwatch.StartNew();
|
LoadConfigByType(configType);
|
sw.Stop();
|
#if UNITY_EDITOR
|
if (sw.ElapsedMilliseconds >= 100)
|
{
|
Debug.LogError($"加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
|
}
|
else if (sw.ElapsedMilliseconds <= 5)
|
{
|
fastName.Add(configType.Name);
|
}
|
Debug.Log($"加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");
|
#endif
|
loadingProgress = (float)(iterator++ + 1) / totalConfigs;
|
}
|
#if UNITY_EDITOR
|
if (Launch.Instance.isOpenConfigTesting)
|
{
|
System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
|
|
//加载完后卸载
|
foreach (var configType in configTypes)
|
{
|
var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
|
if (methodInfo != null)
|
{
|
methodInfo.Invoke(null, null);
|
}
|
}
|
}
|
#endif
|
|
// 加载完成后设置isLoadFinished为true
|
loadingProgress = 1f;
|
isLoadFinished = true;
|
}
|
|
public void LoadConfigByType(Type configType)
|
{
|
string configName = configType.Name;
|
if (configName.EndsWith("Config"))
|
{
|
configName = configName.Substring(0, configName.Length - 6);
|
}
|
string[] texts = ResManager.Instance.LoadConfig(configName);
|
if (texts != null)
|
{
|
string[] lines = texts;
|
var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
|
if (methodInfo != null)
|
{
|
methodInfo.Invoke(null, new object[] { lines });
|
// 设置初始化标志
|
var isInitField = configType.GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
|
if (isInitField != null)
|
{
|
isInitField.SetValue(null, true);
|
}
|
Debug.Log($"加载配置: {configType.Name} 成功");
|
}
|
else
|
{
|
Debug.LogError($"配置类 {configType.Name} 没有静态Init方法");
|
}
|
}
|
else
|
{
|
Debug.LogError($"找不到配置文件: {configName}");
|
}
|
}
|
|
private async UniTask LoadConfig<T>() where T : class
|
{
|
string configName = typeof(T).Name;
|
|
string[] texts = ResManager.Instance.LoadConfig(configName);
|
if (texts != null)
|
{
|
string[] lines = texts;
|
var methodInfo = typeof(T).GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
|
if (methodInfo != null)
|
{
|
methodInfo.Invoke(null, lines);
|
// 设置初始化标志
|
var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
|
if (isInitField != null)
|
{
|
isInitField.SetValue(null, true);
|
}
|
Debug.Log($"加载配置: {typeof(T).Name} 成功");
|
}
|
else
|
{
|
Debug.LogError($"配置类 {typeof(T).Name} 没有静态Init方法");
|
}
|
}
|
else
|
{
|
Debug.LogError($"找不到配置文件: {configName}");
|
}
|
}
|
|
public float GetLoadingProgress()
|
{
|
return loadingProgress;
|
}
|
|
private void ClearConfigDictionary<T>() where T : class
|
{
|
// 重置 T 初始化状态
|
var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
|
if (isInitField != null)
|
{
|
isInitField.SetValue(null, false);
|
}
|
}
|
|
public override void Release()
|
{
|
// 清空 ChestsAwardConfig 字典
|
ClearConfigDictionary<ChestsAwardConfig>();
|
// 清空 CTGConfig 字典
|
ClearConfigDictionary<CTGConfig>();
|
// 清空 DamageNumConfig 字典
|
ClearConfigDictionary<DamageNumConfig>();
|
// 清空 DirtyWordConfig 字典
|
ClearConfigDictionary<DirtyWordConfig>();
|
// 清空 FaceConfig 字典
|
ClearConfigDictionary<FaceConfig>();
|
// 清空 HeroLineupHaloConfig 字典
|
ClearConfigDictionary<HeroLineupHaloConfig>();
|
// 清空 HeroQualityLVConfig 字典
|
ClearConfigDictionary<HeroQualityLVConfig>();
|
// 清空 ItemConfig 字典
|
ClearConfigDictionary<ItemConfig>();
|
// 清空 MainChapterConfig 字典
|
ClearConfigDictionary<MainChapterConfig>();
|
// 清空 MainLevelConfig 字典
|
ClearConfigDictionary<MainLevelConfig>();
|
// 清空 NPCConfig 字典
|
ClearConfigDictionary<NPCConfig>();
|
// 清空 NPCExConfig 字典
|
ClearConfigDictionary<NPCExConfig>();
|
// 清空 NPCLineupConfig 字典
|
ClearConfigDictionary<NPCLineupConfig>();
|
// 清空 OrderInfoConfig 字典
|
ClearConfigDictionary<OrderInfoConfig>();
|
// 清空 PlayerAttrConfig 字典
|
ClearConfigDictionary<PlayerAttrConfig>();
|
// 清空 PlayerFaceConfig 字典
|
ClearConfigDictionary<PlayerFaceConfig>();
|
// 清空 StoreConfig 字典
|
ClearConfigDictionary<StoreConfig>();
|
// 清空 SuccessConfig 字典
|
ClearConfigDictionary<SuccessConfig>();
|
// 清空 SysInfoConfig 字典
|
ClearConfigDictionary<SysInfoConfig>();
|
// 清空 TitleStarUpConfig 字典
|
ClearConfigDictionary<TitleStarUpConfig>();
|
// 清空 TreasureSetConfig 字典
|
ClearConfigDictionary<TreasureSetConfig>();
|
// 清空 TreeLVConfig 字典
|
ClearConfigDictionary<TreeLVConfig>();
|
// 清空 WindowSearchConfig 字典
|
ClearConfigDictionary<WindowSearchConfig>();
|
// 清空 XBGetItemConfig 字典
|
ClearConfigDictionary<XBGetItemConfig>();
|
}
|
|
#if UNITY_EDITOR
|
[MenuItem("Tools/Config/自检")]
|
public static void CheckAndGenerateFastConfig()
|
{
|
// 获取 Editor Assembly
|
var editorAsm = System.AppDomain.CurrentDomain.GetAssemblies()
|
.FirstOrDefault(a => a.FullName.Contains("Editor"));
|
|
if (editorAsm == null)
|
{
|
Debug.LogError("[自检] 未找到 Editor Assembly,无法自检。");
|
return;
|
}
|
|
// 反射获取 ConfigGenerater 类型
|
var configGeneraterType = editorAsm.GetType("ConfigGenerater");
|
if (configGeneraterType == null)
|
{
|
Debug.LogError("[自检] 未找到 ConfigGenerater 类型。");
|
return;
|
}
|
|
// 调用 GetAllConfigClasses 静态方法
|
var getAllConfigClassesMethod = configGeneraterType.GetMethod("GetAllConfigClasses", BindingFlags.Public | BindingFlags.Static);
|
var allConfigClasses = getAllConfigClassesMethod?.Invoke(null, null) as List<string>;
|
if (allConfigClasses == null)
|
{
|
Debug.LogError("[自检] 获取全部配置类失败。");
|
return;
|
}
|
|
// 获取 ExcludeClassList 字段
|
var excludeField = configGeneraterType.GetField("ExcludeClassList", BindingFlags.Public | BindingFlags.Static);
|
var excludeClassList = excludeField?.GetValue(null) as List<string> ?? new List<string>();
|
|
// 排除不需要的类
|
var checkClasses = allConfigClasses.Where(c => !excludeClassList.Contains(c)).ToList();
|
|
List<string> fastName = new List<string>();
|
|
foreach (var className in checkClasses)
|
{
|
// 这里也要用 Editor Assembly 获取类型
|
var configType = editorAsm.GetType(className) ?? Type.GetType(className);
|
if (configType == null)
|
{
|
Debug.LogWarning($"[自检] 未找到类型: {className}");
|
continue;
|
}
|
|
var sw = System.Diagnostics.Stopwatch.StartNew();
|
|
// 反射调用静态Init方法
|
string configName = configType.Name;
|
if (configName.EndsWith("Config"))
|
configName = configName.Substring(0, configName.Length - 6);
|
|
string[] texts = ResManager.Instance.LoadConfig(configName);
|
if (texts != null)
|
{
|
string[] lines = texts;
|
var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
|
if (methodInfo != null)
|
{
|
methodInfo.Invoke(null, new object[] { lines });
|
}
|
}
|
|
sw.Stop();
|
|
if (sw.ElapsedMilliseconds >= 100)
|
{
|
Debug.LogError($"[自检] 加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
|
}
|
else if (sw.ElapsedMilliseconds <= 5)
|
{
|
fastName.Add(configType.Name);
|
}
|
Debug.Log($"[自检] 加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");
|
}
|
|
// 释放所有已加载的配置
|
foreach (var className in checkClasses)
|
{
|
var configType = editorAsm.GetType(className) ?? Type.GetType(className);
|
if (configType == null) continue;
|
var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
|
if (methodInfo != null)
|
{
|
methodInfo.Invoke(null, null);
|
}
|
}
|
|
System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
|
Debug.Log($"[自检] fastConfig.txt 生成完毕,快速表有:{string.Join(", ", fastName)}");
|
}
|
#endif
|
}
|