(client) feat:添加游玩时UI相关贴图,添加3d模型场景按钮,添加多级调色进度条,添加SVG图片包,添加事件定义以及管理器,添加音频管理器,定义部分怪物,添加通信协议定义;fix:修复维度切换错误,修复LogUI显示不正确 (#55)
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: #55
This commit is contained in:
@ -3,152 +3,22 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
|
||||
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
|
||||
using System.Xml.Linq;
|
||||
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
|
||||
using UnityEngine;
|
||||
using Formatting = Newtonsoft.Json.Formatting;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
|
||||
|
||||
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
|
||||
|
||||
namespace Configs
|
||||
{
|
||||
public static class ConfigProcessor
|
||||
{
|
||||
// 保存文件的默认文件夹路径
|
||||
private const string FolderPath = "save";
|
||||
|
||||
/// <summary>
|
||||
/// 初始化文件夹
|
||||
/// </summary>
|
||||
static ConfigProcessor()
|
||||
{
|
||||
if (!Directory.Exists(FolderPath)) Directory.CreateDirectory(FolderPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存单个类为 JSON 文件
|
||||
/// </summary>
|
||||
/// <param name="obj">要保存的类对象</param>
|
||||
/// <param name="fileName">可选的文件名(不包括扩展名)</param>
|
||||
public static bool SaveFile<T>(T obj, string fileName = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 如果未提供文件名,则使用类名作为文件名
|
||||
if (string.IsNullOrEmpty(fileName)) fileName = typeof(T).Name;
|
||||
|
||||
// 构建完整的文件路径
|
||||
var filePath = Path.Combine(FolderPath, fileName + ".json");
|
||||
|
||||
// 将对象序列化为 JSON 字符串
|
||||
var jsonContent = JsonConvert.SerializeObject(obj, Formatting.Indented);
|
||||
|
||||
// 写入文件
|
||||
File.WriteAllText(filePath, jsonContent);
|
||||
|
||||
Debug.Log($"Saved file: {filePath}");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to save file: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 JSON 文件读取单个类
|
||||
/// </summary>
|
||||
/// <param name="fileName">文件名(不包括扩展名)</param>
|
||||
public static T LoadFile<T>(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 构建完整的文件路径
|
||||
var filePath = Path.Combine(FolderPath, fileName + ".json");
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.LogError($"File not found: {filePath}");
|
||||
return default;
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
var jsonContent = File.ReadAllText(filePath);
|
||||
|
||||
// 反序列化为指定类型的对象
|
||||
var obj = JsonConvert.DeserializeObject<T>(jsonContent);
|
||||
|
||||
Debug.Log($"Loaded file: {filePath}");
|
||||
return obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to load file: {ex.Message}");
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打包多个类并保存为一个存档文件
|
||||
/// </summary>
|
||||
/// <param name="archiveName">存档文件名(不包括扩展名)</param>
|
||||
/// <param name="objects">要保存的类对象字典</param>
|
||||
public static bool SaveArchive(string archiveName, Dictionary<string, object> objects)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 构建完整的文件路径
|
||||
var filePath = Path.Combine(FolderPath, archiveName + ".archive.json");
|
||||
|
||||
// 将字典中的对象序列化为 JSON
|
||||
var jsonContent = JsonConvert.SerializeObject(objects, Formatting.Indented);
|
||||
|
||||
// 写入文件
|
||||
File.WriteAllText(filePath, jsonContent);
|
||||
|
||||
Debug.Log($"Saved archive: {filePath}");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to save archive: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从存档文件中读取多个类
|
||||
/// </summary>
|
||||
/// <param name="archiveName">存档文件名(不包括扩展名)</param>
|
||||
public static Dictionary<string, object> LoadArchive(string archiveName)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 构建完整的文件路径
|
||||
var filePath = Path.Combine(FolderPath, archiveName + ".archive.json");
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.LogError($"Archive not found: {filePath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
var jsonContent = File.ReadAllText(filePath);
|
||||
|
||||
// 反序列化为字典
|
||||
var objects = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonContent);
|
||||
|
||||
Debug.Log($"Loaded archive: {filePath}");
|
||||
return objects;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Failed to load archive: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定路径下的所有xml文件
|
||||
@ -161,29 +31,25 @@ namespace Configs
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
// 检查目录是否存在
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
// **逻辑修改 1.1**: 将静默跳过改为记录警告,提供更友好的提示。
|
||||
Debug.LogWarning($"警告: 指定路径不存在或无法访问 - {path}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取目录下的所有子文件夹
|
||||
var subDirectories = Directory.GetDirectories(path);
|
||||
|
||||
// 遍历并收集每个子文件夹中的 XML 文件
|
||||
foreach (var dir in subDirectories)
|
||||
{
|
||||
var xmlFiles = Directory.GetFiles(dir, "*.xml", SearchOption.AllDirectories);
|
||||
xmlFilePaths.AddRange(xmlFiles);
|
||||
}
|
||||
|
||||
// **逻辑修改 1.2**: 原始逻辑仅遍历子文件夹,导致根路径下的XML文件被忽略。
|
||||
// 现修改为直接获取当前路径及其所有子目录中的 XML 文件。
|
||||
var xmlFiles = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories);
|
||||
xmlFilePaths.AddRange(xmlFiles);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"加载文件时发生错误: {ex.Message}");
|
||||
// 优化错误信息,明确是哪个路径出现问题
|
||||
Debug.LogError($"获取路径 '{path}' 下的XML文件时发生错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,20 +166,19 @@ namespace Configs
|
||||
}
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.LogError($"文件不存在: {filePath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] bytes = null;
|
||||
byte[] bytes;
|
||||
|
||||
try
|
||||
{
|
||||
// 使用 using 自动管理 FileStream 的生命周期
|
||||
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
fs.Seek(0, SeekOrigin.Begin); // 将游标移动到文件开头(可选)
|
||||
bytes = new byte[fs.Length]; // 创建一个字节数组来存储文件内容
|
||||
fs.Read(bytes, 0, bytes.Length); // 读取文件内容到字节数组
|
||||
}
|
||||
@ -383,11 +248,93 @@ namespace Configs
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
// 可选:记录日志或忽略无权限目录
|
||||
Console.WriteLine($"访问被拒绝: {ex.Message}");
|
||||
// **逻辑修改 3**: 在 Unity 环境中,应使用 Debug.LogError 而非 Console.WriteLine 记录错误。
|
||||
Debug.LogError($"访问目录 '{directoryPath}' 被拒绝: {ex.Message}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据文件路径推断音频类型。
|
||||
/// </summary>
|
||||
/// <param name="filePath">音频文件的完整路径。</param>
|
||||
/// <returns>推断出的 AudioType,如果无法推断则返回 AudioType.UNKNOWN。</returns>
|
||||
private static AudioType GetAudioTypeFromFilePath(string filePath)
|
||||
{
|
||||
string ext = Path.GetExtension(filePath)?.ToLower(); // 获取扩展名并转小写
|
||||
switch (ext)
|
||||
{
|
||||
case ".wav": return AudioType.WAV;
|
||||
case ".mp3": return AudioType.MPEG;
|
||||
case ".ogg": return AudioType.OGGVORBIS;
|
||||
case ".aiff": return AudioType.AIFF;
|
||||
// 可以根据需要添加更多常见的音频类型
|
||||
default:
|
||||
Debug.LogWarning($"警告: 未知音频文件类型 '{ext}' for file '{filePath}'. 尝试使用 AudioType.UNKNOWN.");
|
||||
return AudioType.UNKNOWN; // 让Unity尝试自动检测,但成功率可能不如指定类型高
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 从外部指定文件中异步加载音频。
|
||||
/// 注意:此方法是异步的,需要使用 await 调用。在Unity主线程中调用以避免潜在的线程问题。
|
||||
/// </summary>
|
||||
/// <param name="filePath">音频文件的完整路径。</param>
|
||||
/// <returns>Task,其结果为加载成功的 AudioClip 对象,或加载失败时返回 null。</returns>
|
||||
public static async Task<AudioClip> LoadAudioByIO(string filePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
Debug.LogError("音频文件路径为空,请检查输入!");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Debug.LogError($"音频文件不存在: {filePath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// UnityWebRequest需要使用file://协议来访问本地文件
|
||||
string uri = "file://" + Path.GetFullPath(filePath);
|
||||
// 根据文件扩展名推断音频类型
|
||||
AudioType audioType = GetAudioTypeFromFilePath(filePath);
|
||||
|
||||
using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(uri, audioType))
|
||||
{
|
||||
try
|
||||
{
|
||||
// 发送请求并等待完成
|
||||
// await www.SendWebRequest(); 是核心,它会异步执行网络请求。
|
||||
// 如果在Unity Editor中遇到“You are trying to load data from a www stream that had a non-OK status”等错误,
|
||||
// 可以检查文件路径和文件权限。
|
||||
await www.SendWebRequest();
|
||||
|
||||
// 检查请求结果
|
||||
// www.isNetworkError 或 www.isHttpError 在较新的Unity版本中已弃用,
|
||||
// 推荐使用 www.result。
|
||||
if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
Debug.LogError($"加载音频文件 '{filePath}' 失败: {www.error}");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 获取下载的AudioClip
|
||||
AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
|
||||
if (clip == null)
|
||||
{
|
||||
Debug.LogError($"未能从文件 '{filePath}' 获取 AudioClip 内容,请检查文件是否损坏或格式是否支持 ({audioType} 类型).");
|
||||
}
|
||||
return clip;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"处理音频文件 '{filePath}' 时发生异常: {e.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user