using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
using System.Xml.Linq;
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
using UnityEngine;
using UnityEngine.Networking;
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
// 未在提供代码段中使用,但保留以便与原始上下文保持一致
namespace Configs
{
public static class ConfigProcessor
{
///
/// 获取指定路径下的所有xml文件
///
/// 文件夹路径
///
public static List GetXmlFilePathsFromPaths(string[] paths)
{
var xmlFilePaths = new List();
foreach (var path in paths)
{
try
{
// 检查目录是否存在
if (!Directory.Exists(path))
{
// **逻辑修改 1.1**: 将静默跳过改为记录警告,提供更友好的提示。
Debug.LogWarning($"警告: 指定路径不存在或无法访问 - {path}");
continue;
}
// **逻辑修改 1.2**: 原始逻辑仅遍历子文件夹,导致根路径下的XML文件被忽略。
// 现修改为直接获取当前路径及其所有子目录中的 XML 文件。
var xmlFiles = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories);
xmlFilePaths.AddRange(xmlFiles);
}
catch (Exception ex)
{
// 优化错误信息,明确是哪个路径出现问题
Debug.LogError($"获取路径 '{path}' 下的XML文件时发生错误: {ex.Message}");
}
}
return xmlFilePaths;
}
///
/// 从指定路径加载所有 XML 文件并解析为 XDocument 对象。
///
/// 文件夹路径数组。
/// 包含所有解析后的 XDocument 对象的列表。
public static List LoadXmlFromPaths(string[] paths)
{
var xDocuments = new List();
var xmlFilePaths = GetXmlFilePathsFromPaths(paths);
foreach (var filePath in xmlFilePaths)
try
{
var xDoc = XDocument.Load(filePath);
xDocuments.Add(xDoc);
}
catch (Exception ex)
{
Debug.LogError($"加载 XML 文件 {filePath} 时发生错误: {ex.Message}");
}
return xDocuments;
}
///
/// 获取指定单个路径下的所有 XML 文件。
///
/// 文件夹路径。
/// 包含所有 XML 文件路径的列表。
public static List GetXmlFilePathsFromPath(string path)
{
return GetXmlFilePathsFromPaths(new[] { path });
}
///
/// 从指定单个路径加载所有 XML 文件并解析为 XDocument 对象。
///
/// 文件夹路径。
/// 包含所有解析后的 XDocument 对象的列表。
public static List LoadXmlFromPath(string path)
{
return LoadXmlFromPaths(new[] { path });
}
///
/// 获取文件夹列表中所有直接子文件夹的路径。
///
/// 文件夹路径列表。
/// 包含所有子文件夹路径的列表。
public static List GetSubFolders(List folderPaths)
{
var result = new List();
foreach (var folderPath in folderPaths)
if (Directory.Exists(folderPath))
{
// 获取当前文件夹的直接子文件夹
var subFolders = Directory.GetDirectories(folderPath);
// 将子文件夹路径添加到结果列表中
result.AddRange(subFolders);
}
else
{
Debug.LogWarning($"警告: 文件夹不存在 - {folderPath}");
}
return result;
}
///
/// 用于加载指定路径下的所有资源,并返回资源名称和加载好的资源的键值对。
///
/// 资源类型
/// 资源路径(相对于 Resources 文件夹)
/// 字典,键为资源名称,值为加载好的资源
public static Dictionary LoadResources(string path) where T : UnityEngine.Object
{
// 创建一个字典来存储资源名称和加载好的资源
var resourceDict = new Dictionary();
// 加载指定路径下的所有资源
var resources = Resources.LoadAll(path);
foreach (var resource in resources)
{
if (resource != null)
{
// 获取资源名称并存入字典
var resourceName = resource.name;
resourceDict[resourceName] = resource;
}
}
return resourceDict;
}
///
/// 从外部指定文件中加载图片
///
/// 图片文件的完整路径
/// 加载成功的 Texture2D 对象,或加载失败时返回 null
public static Texture2D LoadTextureByIO(string filePath)
{
if (string.IsNullOrEmpty(filePath))
{
Debug.LogError("文件路径为空,请检查输入!");
return null;
}
// 检查文件是否存在
if (!File.Exists(filePath))
{
Debug.LogError($"文件不存在: {filePath}");
return null;
}
byte[] bytes;
try
{
// 使用 using 自动管理 FileStream 的生命周期
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
bytes = new byte[fs.Length]; // 创建一个字节数组来存储文件内容
fs.Read(bytes, 0, bytes.Length); // 读取文件内容到字节数组
}
}
catch (Exception e)
{
Debug.LogError($"读取文件时发生错误: {e.Message}");
return null;
}
// 创建一个默认大小的 Texture2D 对象
var texture = new Texture2D(2, 2, TextureFormat.RGBA32, false); // 初始大小为 2x2,LoadImage 会自动调整大小
if (texture.LoadImage(bytes)) // 加载图片数据
{
// 设置过滤模式为 Point (无插值)
texture.filterMode = FilterMode.Point;
texture.wrapMode = TextureWrapMode.Clamp; // 防止边缘出现意外拉伸
return texture; // 返回加载成功的 Texture2D 对象
}
else
{
Debug.LogError("图片加载失败,请检查文件格式是否正确!");
return null;
}
}
///
/// 获取指定目录下所有匹配后缀名的文件路径(可递归)
///
/// 目标文件夹路径
/// 后缀名列表(如 ["txt", "jpg"])
/// 是否包含子文件夹
/// 匹配的文件路径列表
public static List GetFilesByExtensions(
string directoryPath,
string[] extensions,
SearchOption searchOption = SearchOption.AllDirectories)
{
if (string.IsNullOrWhiteSpace(directoryPath))
throw new ArgumentException("目录路径不能为空", nameof(directoryPath));
if (!Directory.Exists(directoryPath))
throw new DirectoryNotFoundException($"目录不存在: {directoryPath}");
if (extensions == null || extensions.Length == 0)
throw new ArgumentException("后缀名列表不能为空", nameof(extensions));
// 标准化后缀名(去掉点,转小写)
var normalizedExtensions = new HashSet(
extensions.Select(ext => ext.TrimStart('.').ToLower())
);
var result = new List();
try
{
var files = Directory.GetFiles(directoryPath, "*", searchOption);
foreach (var file in files)
{
var ext = Path.GetExtension(file).TrimStart('.').ToLower();
if (normalizedExtensions.Contains(ext))
{
result.Add(file);
}
}
}
catch (UnauthorizedAccessException ex)
{
// **逻辑修改 3**: 在 Unity 环境中,应使用 Debug.LogError 而非 Console.WriteLine 记录错误。
Debug.LogError($"访问目录 '{directoryPath}' 被拒绝: {ex.Message}");
}
return result;
}
///
/// 根据文件路径推断音频类型。
///
/// 音频文件的完整路径。
/// 推断出的 AudioType,如果无法推断则返回 AudioType.UNKNOWN。
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尝试自动检测,但成功率可能不如指定类型高
}
}
///
/// 从外部指定文件中异步加载音频。
/// 注意:此方法是异步的,需要使用 await 调用。在Unity主线程中调用以避免潜在的线程问题。
///
/// 音频文件的完整路径。
/// Task,其结果为加载成功的 AudioClip 对象,或加载失败时返回 null。
public static async Task 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;
}
}
}
}
}