本代码只有读取文件夹中的图片、txt文档、子文件夹功能。可以将层级体现在一个list中。后续根据所需去遍历寻找对应的就好。
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
/// <summary>
/// 通用文件夹节点 - 可以表示任意层级的文件夹结构
/// </summary>
[Serializable]
public class FolderNode
{
public string folderName; // 文件夹名称
public string fullPath; // 完整路径
public List<TextFile> textFiles; // 当前文件夹下的所有文本文件
public List<ImageFile> imageFiles; // 当前文件夹下的所有图片文件
public List<FolderNode> subFolders; // 子文件夹列表
public FolderNode(string name, string path)
{
folderName = name;
fullPath = path;
textFiles = new List<TextFile>();
imageFiles = new List<ImageFile>();
subFolders = new List<FolderNode>();
}
}
/// <summary>
/// 文本文件数据
/// </summary>
[Serializable]
public class TextFile
{
public string fileName; // 文件名(带扩展名)
public string fileNameWithoutExtension; // 文件名(不带扩展名)
public string content; // 文件内容
public string fullPath; // 完整路径
public int GetAsInt()
{
int.TryParse(content, out int result);
return result;
}
public float GetAsFloat()
{
float.TryParse(content, out float result);
return result;
}
}
/// <summary>
/// 图片文件数据
/// </summary>
[Serializable]
public class ImageFile
{
public string fileName; // 文件名
public string fileNameWithoutExtension; // 文件名(不带扩展名)
public Sprite sprite; // 加载的精灵
public Texture2D texture; // 原始贴图
public string fullPath; // 完整路径
}
/// <summary>
/// 通用数据加载器
/// </summary>
public class DataLoader : MonoBehaviour
{
public static DataLoader Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
}
else
{
Instance = this;
// 可选:使单例对象在加载新场景时不被销毁
// DontDestroyOnLoad(gameObject);
}
}
[Header("配置")]
[SerializeField] private string relativePath = "YourDataFolder"; // StreamingAssets 下的相对路径
[Header("加载选项")]
[SerializeField] private bool loadTextContent = true; // 是否加载文本内容
[SerializeField] private bool loadImages = true; // 是否加载图片
[SerializeField] private bool keepTextureReference = false; // 是否保留 Texture2D 引用(节省内存可关闭)
[Header("运行时数据")]
public FolderNode rootNode; // 根节点
public static FolderNode rootNode_Static;
void Start()
{
LoadData();
// 使用示例
//ExampleUsage();
rootNode_Static = rootNode;
}
/// <summary>
/// 加载数据的入口方法
/// </summary>
public void LoadData()
{
string rootPath = Path.Combine(Application.streamingAssetsPath, relativePath);
if (!Directory.Exists(rootPath))
{
Debug.LogError($"根目录不存在: {rootPath}");
return;
}
Debug.Log($"开始加载: {rootPath}");
float startTime = Time.realtimeSinceStartup;
// 递归加载整个文件夹树
rootNode = LoadFolderRecursive(rootPath);
float loadTime = (Time.realtimeSinceStartup - startTime) * 1000f;
Debug.Log($"加载完成!耗时: {loadTime:F2}ms");
PrintStatistics(rootNode);
}
/// <summary>
/// 递归加载文件夹及其所有内容
/// </summary>
FolderNode LoadFolderRecursive(string folderPath)
{
string folderName = Path.GetFileName(folderPath);
FolderNode node = new FolderNode(folderName, folderPath);
// 1. 加载当前文件夹下的所有文本文件
if (loadTextContent)
{
string[] txtFiles = Directory.GetFiles(folderPath, "*.txt");
foreach (string txtPath in txtFiles)
{
TextFile textFile = new TextFile
{
fileName = Path.GetFileName(txtPath),
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(txtPath),
content = File.ReadAllText(txtPath).Trim(),
fullPath = txtPath
};
node.textFiles.Add(textFile);
}
}
// 2. 加载当前文件夹下的所有图片文件
if (loadImages)
{
string[] imageExtensions = { "*.png", "*.jpg", "*.jpeg" };
foreach (string ext in imageExtensions)
{
string[] imageFiles = Directory.GetFiles(folderPath, ext);
foreach (string imgPath in imageFiles)
{
ImageFile imageFile = LoadImage(imgPath);
if (imageFile != null)
{
node.imageFiles.Add(imageFile);
}
}
}
}
// 3. 递归加载所有子文件夹
string[] subDirs = Directory.GetDirectories(folderPath);
foreach (string subDir in subDirs)
{
FolderNode childNode = LoadFolderRecursive(subDir);
node.subFolders.Add(childNode);
}
return node;
}
/// <summary>
/// 加载单个图片文件
/// </summary>
ImageFile LoadImage(string imagePath)
{
try
{
byte[] fileData = File.ReadAllBytes(imagePath);
Texture2D texture = new Texture2D(2, 2);
if (texture.LoadImage(fileData))
{
Sprite sprite = Sprite.Create(
texture,
new Rect(0, 0, texture.width, texture.height),
new Vector2(0.5f, 0.5f)
);
ImageFile imageFile = new ImageFile
{
fileName = Path.GetFileName(imagePath),
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(imagePath),
sprite = sprite,
texture = keepTextureReference ? texture : null,
fullPath = imagePath
};
return imageFile;
}
else
{
Debug.LogError($"图片加载失败: {imagePath}");
return null;
}
}
catch (Exception e)
{
Debug.LogError($"读取图片异常: {imagePath}\n{e.Message}");
return null;
}
}
/// <summary>
/// 打印统计信息
/// </summary>
void PrintStatistics(FolderNode node)
{
int totalFolders = 0;
int totalTextFiles = 0;
int totalImages = 0;
CountRecursive(node, ref totalFolders, ref totalTextFiles, ref totalImages);
Debug.Log($"=== 加载统计 ===");
Debug.Log($"文件夹总数: {totalFolders}");
Debug.Log($"文本文件总数: {totalTextFiles}");
Debug.Log($"图片文件总数: {totalImages}");
}
void CountRecursive(FolderNode node, ref int folders, ref int texts, ref int images)
{
folders++;
texts += node.textFiles.Count;
images += node.imageFiles.Count;
foreach (var child in node.subFolders)
{
CountRecursive(child, ref folders, ref texts, ref images);
}
}
// ==================== 数据访问辅助方法 ====================
/// <summary>
/// 根据路径查找文件夹节点(支持相对路径)
/// 例如: "Panel1/Items/Item01"
/// </summary>
public FolderNode FindFolder(string relativePath)
{
if (rootNode == null) return null;
string[] parts = relativePath.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
FolderNode current = rootNode;
foreach (string part in parts)
{
current = current.subFolders.Find(f => f.folderName == part);
if (current == null)
{
Debug.LogWarning($"未找到文件夹: {relativePath}");
return null;
}
}
return current;
}
/// <summary>
/// 在指定节点下查找文本文件
/// </summary>
public static TextFile FindTextFile(FolderNode node, string fileNameWithoutExt)
{
if (node == null) return null;
return node.textFiles.Find(f => f.fileNameWithoutExtension == fileNameWithoutExt);
}
/// <summary>
/// 在指定节点下查找图片文件
/// </summary>
public ImageFile FindImageFile(FolderNode node, string fileNameWithoutExt)
{
if (node == null) return null;
return node.imageFiles.Find(f => f.fileNameWithoutExtension == fileNameWithoutExt);
}
/// <summary>
/// 获取所有符合条件的节点(深度搜索)
/// </summary>
public List<FolderNode> FindAllFoldersWithName(string folderName)
{
List<FolderNode> results = new List<FolderNode>();
SearchRecursive(rootNode, folderName, results);
return results;
}
void SearchRecursive(FolderNode node, string targetName, List<FolderNode> results)
{
if (node.folderName == targetName)
{
results.Add(node);
}
foreach (var child in node.subFolders)
{
SearchRecursive(child, targetName, results);
}
}
// ==================== 使用示例 ====================
void ExampleUsage()
{
if (rootNode == null) return;
Debug.Log("\n=== 使用示例 ===");
// 示例1: 遍历根目录下的所有子文件夹
Debug.Log($"\n根目录下有 {rootNode.subFolders.Count} 个子文件夹:");
foreach (var folder in rootNode.subFolders)
{
Debug.Log($" - {folder.folderName}");
}
// 示例2: 查找特定路径的文件夹
FolderNode targetFolder = FindFolder("Panel1/Items");
if (targetFolder != null)
{
Debug.Log($"\n找到文件夹: {targetFolder.folderName}");
Debug.Log($" 包含 {targetFolder.textFiles.Count} 个文本文件");
Debug.Log($" 包含 {targetFolder.imageFiles.Count} 个图片");
}
// 示例3: 读取特定文本文件
if (rootNode.subFolders.Count > 0)
{
var firstFolder = rootNode.subFolders[0];
var nameFile = FindTextFile(firstFolder, "name");
if (nameFile != null)
{
Debug.Log($"\n读取到文本: {nameFile.fileNameWithoutExtension} = {nameFile.content}");
}
}
// 示例4: 查找所有名为 "Items" 的文件夹
var itemsFolders = FindAllFoldersWithName("Items");
Debug.Log($"\n找到 {itemsFolders.Count} 个名为 'Items' 的文件夹");
}
}