mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-20 05:37:11 +08:00
(client) feat:实现技能树界面,实现地图生成器,实现维度指定,实现规则瓦片定义,实现逃跑逻辑,实现消息定义,实现武器动画,实现受击动画 fix: 修复单攻击子弹击中多个目标,修复人物属性计算错误 (#56)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/56
This commit is contained in:
230
Client/Assets/Scripts/Configs/ConfigManager.cs
Normal file
230
Client/Assets/Scripts/Configs/ConfigManager.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Managers;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Configs
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置管理器,采用单例模式,负责读取、修改、存储应用程序配置。
|
||||
/// 继承自 Utils.Singleton<ConfigManager> 和 ILaunchManager。
|
||||
/// </summary>
|
||||
public class ConfigManager : Utils.Singleton<ConfigManager>, ILaunchManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置文件名
|
||||
/// </summary>
|
||||
private const string CONFIG_FILE_NAME = "app_config.json";
|
||||
|
||||
/// <summary>
|
||||
/// 完整的配置文件路径
|
||||
/// Application.persistentDataPath 在PC上是 C:/Users/用户名/AppData/LocalLow/公司名/项目名/,
|
||||
/// 在Android/iOS上是持久存储路径。
|
||||
/// </summary>
|
||||
private readonly string _configFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// 存储配置数据的字典。使用 JToken 允许存储任意 JSON 类型(基本类型、对象、数组)。
|
||||
/// </summary>
|
||||
private Dictionary<string, JToken> _configData;
|
||||
|
||||
/// <summary>
|
||||
/// 私有构造函数,由 Singleton 基类调用。
|
||||
/// </summary>
|
||||
public ConfigManager()
|
||||
{
|
||||
_configFilePath = Path.Combine(Application.persistentDataPath, CONFIG_FILE_NAME);
|
||||
_configData = new Dictionary<string, JToken>();
|
||||
Debug.Log($"ConfigManager initialized. Config file path: {_configFilePath}");
|
||||
}
|
||||
|
||||
public string StepDescription => "载入配置文件";
|
||||
|
||||
/// <summary>
|
||||
/// 初始化配置管理器,加载配置文件。
|
||||
/// 如果配置文件不存在,将创建一个默认配置。
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
LoadConfig();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理配置管理器,释放内存中的配置数据。
|
||||
/// 注意:此方法不会自动保存配置。如果需要在清理前保存,请手动调用 Save()。
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_configData.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从配置文件加载配置数据到内存。
|
||||
/// 如果文件不存在,则创建默认配置并保存。
|
||||
/// </summary>
|
||||
private void LoadConfig()
|
||||
{
|
||||
if (File.Exists(_configFilePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = File.ReadAllText(_configFilePath);
|
||||
_configData = JsonConvert.DeserializeObject<Dictionary<string, JToken>>(json);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"ConfigManager: Failed to deserialize config file. Creating default config. Error: {ex.Message}");
|
||||
CreateDefaultConfig();
|
||||
SaveConfig(); // 保存默认配置
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"ConfigManager: Failed to read config file. Creating default config. Error: {ex.Message}");
|
||||
CreateDefaultConfig();
|
||||
SaveConfig(); // 保存默认配置
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("ConfigManager: Config file not found. Creating default config.");
|
||||
CreateDefaultConfig();
|
||||
SaveConfig(); // 保存默认配置
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个默认的空配置或包含初始值的配置。
|
||||
/// </summary>
|
||||
private void CreateDefaultConfig()
|
||||
{
|
||||
_configData = new Dictionary<string, JToken>();
|
||||
SetValue("playerAffiliation","player");
|
||||
SetValue("outsideDimension","DefaultOutsideDimension");
|
||||
SetValue("insideDimension","DefaultInsideDimension");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将内存中的配置数据保存到配置文件。
|
||||
/// </summary>
|
||||
public void SaveConfig()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用 Formatting.Indented 使 JSON 文件更具可读性
|
||||
string json = JsonConvert.SerializeObject(_configData, Formatting.Indented);
|
||||
File.WriteAllText(_configFilePath, json);
|
||||
Debug.Log("ConfigManager: Configuration saved successfully.");
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
Debug.LogError($"ConfigManager: Failed to serialize config data. Error: {ex.Message}");
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Debug.LogError($"ConfigManager: Failed to write config file. Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定键的配置值。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值的目标类型。</typeparam>
|
||||
/// <param name="key">配置项的键。</param>
|
||||
/// <param name="defaultValue">如果键不存在或类型转换失败,返回的默认值。</param>
|
||||
/// <returns>配置值或默认值。</returns>
|
||||
public T GetValue<T>(string key, T defaultValue = default(T))
|
||||
{
|
||||
if (_configData.TryGetValue(key, out JToken jToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
// JToken.ToObject<T>() 能够智能地将 JToken 转换为目标类型 T
|
||||
return jToken.ToObject<T>();
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"ConfigManager: Failed to convert value for key '{key}' to type '{typeof(T).Name}'. " +
|
||||
$"Returning default value. Error: {ex.Message}");
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning($"ConfigManager: Key '{key}' not found. Returning default value '{defaultValue}'.");
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置指定键的配置值。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">值的类型。</typeparam>
|
||||
/// <param name="key">配置项的键。</param>
|
||||
/// <param name="value">要设置的值。</param>
|
||||
public void SetValue<T>(string key, T value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
Debug.LogError("ConfigManager: Cannot set value with an empty or null key.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// JToken.FromObject(value) 能够将任何对象转换为 JToken
|
||||
_configData[key] = JToken.FromObject(value);
|
||||
Debug.Log(
|
||||
$"ConfigManager: Value for key '{key}' set to '{value}'. Remember to call SaveConfig() to persist changes.");
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"ConfigManager: Failed to convert value '{value}' for key '{key}' to JToken. Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查配置中是否存在某个键。
|
||||
/// </summary>
|
||||
/// <param name="key">要检查的键。</param>
|
||||
/// <returns>如果存在该键,则为 true;否则为 false。</returns>
|
||||
public bool ContainsKey(string key)
|
||||
{
|
||||
return _configData.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除指定键的配置项。
|
||||
/// </summary>
|
||||
/// <param name="key">要移除的键。</param>
|
||||
/// <returns>如果成功移除,则为 true;否则为 false。</returns>
|
||||
public bool RemoveKey(string key)
|
||||
{
|
||||
if (_configData.Remove(key))
|
||||
{
|
||||
Debug.Log($"ConfigManager: Key '{key}' removed. Remember to call SaveConfig() to persist changes.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"ConfigManager: Attempted to remove non-existent key '{key}'.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 直接获取原始的 JToken 值,适用于处理复杂或嵌套的 JSON 结构。
|
||||
/// </summary>
|
||||
/// <param name="key">配置项的键。</param>
|
||||
/// <returns>对应的 JToken;如果键不存在,则为 null。</returns>
|
||||
public JToken GetRawJToken(string key)
|
||||
{
|
||||
_configData.TryGetValue(key, out JToken jToken);
|
||||
return jToken;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
3
Client/Assets/Scripts/Configs/ConfigManager.cs.meta
Normal file
3
Client/Assets/Scripts/Configs/ConfigManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 560cee81790340d49d6e0bc82a6968a9
|
||||
timeCreated: 1757906609
|
||||
Reference in New Issue
Block a user