Files
godot-------/Script/Pawn/CharacterLoader.cs

232 lines
8.5 KiB
C#
Raw Normal View History

2025-07-12 11:30:22 +08:00
using Godot;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
namespace Cosmobox
{
public static class CharacterLoader
{
// 支持的部件目录列表
private static readonly string[] ComponentFolders = {
"body", "clothing", "hair", "hairBackground", "head", "leftEar", "rightEar"
};
// 方向关键词映射到索引位置
private static readonly Dictionary<string, int> DirectionMapping = new Dictionary<string, int>(System.StringComparer.OrdinalIgnoreCase)
{
{"south", 0}, // 南方向 - 索引0
{"north", 1}, // 北方向 - 索引1
{"east", 2}, // 东方向 - 索引2
{"west", 2} // 西方向也映射到索引2共用东方向的纹理
};
/// <summary>
/// 加载角色所有部件的纹理
/// </summary>
public static Dictionary<string, Texture2D[]> LoadCharacterTextures(string rootPath)
{
var textures = new Dictionary<string, Texture2D[]>();
// GD.Print($"开始加载角色纹理资源,根目录: {rootPath}");
// 检查根目录是否存在
if (!DirAccess.DirExistsAbsolute(rootPath))
{
// GD.PrintErr($"错误:资源根目录不存在 - {rootPath}");
return textures;
}
using (var dir = DirAccess.Open(rootPath))
{
if (dir == null)
{
GD.PrintErr($"错误:无法打开根目录 - {rootPath}");
return textures;
}
// GD.Print($"找到根目录,开始扫描部件文件夹...");
// 遍历所有支持的部件目录
foreach (string component in ComponentFolders)
{
string componentPath = Path.Combine(rootPath, component);
// GD.Print($"检查部件: {component},路径: {componentPath}");
if (DirAccess.DirExistsAbsolute(componentPath))
{
// GD.Print($"找到部件文件夹: {component}");
Texture2D[] componentTextures = LoadComponentTextures(componentPath);
if (componentTextures != null && componentTextures.Length == 3)
{
// GD.Print($"成功加载部件: {component},纹理数量: 3");
textures[component] = componentTextures;
}
else
{
GD.PrintErr($"警告:部件{component}纹理加载不完整,实际数量: {componentTextures?.Length ?? 0}");
}
}
else
{
// GD.Print($"部件文件夹不存在: {component}");
}
}
}
// GD.Print($"资源加载完成,成功部件: {textures.Count}/{ComponentFolders.Length}");
return textures;
}
/// <summary>
/// 加载单个部件的所有方向纹理
/// </summary>
private static Texture2D[] LoadComponentTextures(string folderPath)
{
Texture2D[] textures = new Texture2D[3];
var foundFiles = new List<(string path, int index)>();
// GD.Print($"加载部件文件夹: {folderPath}");
using (var dir = DirAccess.Open(folderPath))
{
if (dir == null)
{
GD.PrintErr($"错误:无法打开部件目录 - {folderPath}");
return textures;
}
var status = dir.ListDirBegin();
if (status != Error.Ok)
{
GD.PrintErr($"错误:无法开始文件列表 ({status}) - {folderPath}");
return textures;
}
string fileName = dir.GetNext();
int fileCount = 0;
int matchedCount = 0;
List<string> unmatchedFiles = new List<string>();
// GD.Print($"开始扫描文件...");
while (!string.IsNullOrEmpty(fileName))
{
fileCount++;
if (!dir.CurrentIsDir())
{
string filePath = Path.Combine(folderPath, fileName);
// GD.Print($"处理文件 #{fileCount}: {fileName}");
// 检查文件扩展名
if (!IsImageFile(fileName))
{
// GD.Print($"跳过非图片文件: {fileName}");
fileName = dir.GetNext();
continue;
}
bool matched = false;
// 检测方向关键词
foreach (var kv in DirectionMapping)
{
if (fileName.Contains(kv.Key, System.StringComparison.OrdinalIgnoreCase))
{
// GD.Print($"找到方向关键词 '{kv.Key}' -> 索引 {kv.Value}");
foundFiles.Add((filePath, kv.Value));
matched = true;
matchedCount++;
break;
}
}
if (!matched)
{
GD.PrintErr($"警告:无法识别的方向名称 - {fileName}");
unmatchedFiles.Add(fileName);
}
}
else
{
// GD.Print($"跳过子目录: {fileName}");
}
fileName = dir.GetNext();
}
dir.ListDirEnd();
// GD.Print($"文件夹扫描完成:");
// GD.Print($"- 总文件: {fileCount}");
// GD.Print($"- 匹配文件: {matchedCount}");
if (unmatchedFiles.Count > 0)
{
GD.PrintErr($"警告: {unmatchedFiles.Count} 个文件未包含方向关键词(south/north/east/west):");
foreach (var f in unmatchedFiles)
{
GD.PrintErr($" - {f}");
}
}
}
// 检查是否所有方向都找到了文件
bool[] foundDirections = new bool[3];
// 加载纹理
foreach (var (path, index) in foundFiles)
{
if (index >= 0 && index < textures.Length)
{
if (textures[index] == null)
{
// GD.Print($"加载纹理: {Path.GetFileName(path)} -> 方向索引 {index}");
textures[index] = ResourceLoader.Load<Texture2D>(path);
foundDirections[index] = true;
if (textures[index] == null)
{
GD.PrintErr($"错误:无法加载纹理资源 - {path}");
}
}
else
{
GD.Print($"跳过纹理: {Path.GetFileName(path)} -> 方向索引 {index}(已有更优先的纹理)");
}
}
else
{
GD.PrintErr($"错误:无效方向索引 {index} - {path}");
}
}
// 检查缺失的方向
for (int i = 0; i < foundDirections.Length; i++)
{
if (!foundDirections[i])
{
string direction;
if (i == 0) direction = "south";
else if (i == 1) direction = "north";
else direction = "east";
GD.PrintErr($"警告:缺少{direction}方向纹理");
}
}
return textures;
}
/// <summary>
/// 检查文件是否是图片格式
/// </summary>
private static bool IsImageFile(string fileName)
{
string ext = Path.GetExtension(fileName).ToLower();
return ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".bmp";
}
}
}