Files
godot-------/Script/Pawn/CharacterLoader.cs
m0_75251201 7700703099 初次提交
2025-07-12 11:30:22 +08:00

232 lines
8.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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";
}
}
}