功能:指定目标文件绝对路径,寻找该路径下目标文件
以下是C#版本代码
/// <summary>
/// 遍历目标路径下所有文件寻找目标文件
/// 找到文件后设置curPath为目标文件的Resources下的相对路径
/// </summary>
/// <param name="dirs">遍历的绝对路径</param>
/// <param name="name">目标文件名(包含后缀)</param>
private void director(string dirs,string name) {
//绑定到指定的文件夹目录
DirectoryInfo dir = new DirectoryInfo(dirs);
//检索表示当前目录的文件和子目录
FileSystemInfo[] fsinfos = dir.GetFileSystemInfos();
//遍历检索的文件和子目录
foreach (FileSystemInfo fsinfo in fsinfos) {
//判断是否为空文件夹
if (fsinfo is DirectoryInfo) {
//如果是文件夹,则递归调用
director(fsinfo.FullName, name);
}
//判断文件名字是否符合目标
else if(fsinfo.Name == name)
{
Debug.Log(fsinfo.FullName);
//分割绝对路径FullName,寻找Resource,然后拼接接下来的字符串作为结果
//绝对路径是使用'\'划分,使用转义字符
string[] gets = fsinfo.FullName.Split('\\');
//判定是否找到目标点
bool isFind = false;
for (int i = 0; i < gets.Length; i++) {
if (isFind) {
//拼接
if (name.CompareTo(gets[i])==0) {
//如果拼接时找到目标点,则去除其后缀
string[] end = gets[i].Split('.');
curPath += end[0];
}
else {
//如果拼接时不是目标点,则加个后缀'/'(文件夹没有后缀,不需要分割截取)
curPath += gets[i] + "/";
}
}
//找到拼接起始点(basic_resources = "Resources")
if (gets[i].CompareTo(basic_resources) == 0) {
//在此进行字符串拼接
isFind = true;
}
}//for_end
}
}//foreach_end
return;
}
/// <summary>
/// UI窗口读取
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject Load_UI(string name) {
GameObject prefab = null;
//basic_ui = "ui/";
string path = basic_ui + "Win_" + name;
//应该改为在basic_ui文件夹下寻找是否符合name的文件
/*测试*/
//初始化curPath
curPath = "";
director(Application.dataPath+"/Resources/"+ basic_ui, "Win_" + name+".prefab");
Debug.Log("结果路径:"+ curPath);
prefab = Resources.Load(curPath) as GameObject;
Debug.Log("寻找预设体:"+prefab);
//prefab = Resources.Load(path) as GameObject;
if (prefab == null) {
Debug.LogError("Failed UIPrb_Local from " + path);
}
return prefab;
}
结果:
请求3个UIPanel,并成功寻找到了,设置其节点为UIRoot2D.NormalPanel下。其中一个Panel存放在UI/Prefab/New Folder,也成功访问到了。
不足:
如果目标路径下有其他相同的目标文件,只会更新到最后一个目标文件。正常情况下,Panel中只会有一个目标文件,可以在director进行判定以及异常信息,当有人为意外误操作时可以及时移除多余文件。或者手动进行文件搜索进行重复排查。
以下是新的优化的版本。添加了剪枝(优化性能)与重置数据。并针对上述的不足在备注里给了一种可能的解决方案。
private string curPath = "";
/// <summary>
/// 遍历目标路径下所有文件寻找目标文件,当找到第一个符合条件的目标后结束遍历
/// 找到文件后设置curPath为目标文件的Resources下的相对路径
/// </summary>
/// <param name="dirs">遍历的绝对路径</param>
/// <param name="name">目标文件名(包含后缀)</param>
/// <param name="isFirst">若为true,则重置curPath</param>
private void director(string dirs,string name,bool isFirst = false) {
//如果是true,则重置curPath值
if (isFirst) {
curPath = "";
}
//若不为空,则说明未重置curPath为空或已找到路径。默认情况下为已找到路径-结束整个遍历搜索
if (!String.IsNullOrEmpty(curPath)) {
return;
}
//绑定到指定的文件夹目录
DirectoryInfo dir = new DirectoryInfo(dirs);
//检索表示当前目录的文件和子目录
FileSystemInfo[] fsinfos = dir.GetFileSystemInfos();
//遍历检索的文件和子目录
foreach (FileSystemInfo fsinfo in fsinfos) {
//判断是否为空文件夹
if (fsinfo is DirectoryInfo) {
//如果是文件夹,则递归调用
director(fsinfo.FullName, name);
}
//判断文件名字是否符合目标
else if(fsinfo.Name == name)
{
/* 若需要反馈重复目标,则可能需要这一句。本方法功能是遇到第一个符合条件就结束寻找。所以该逻辑不会运行到(若想运行则移除该方法头部的剪枝语句)。
* 读者可根据实际情况进行选择
//如果找到一个新的符合目标文件,判定curPath是否为空。若不为空,则说明是重复目标,提示错误
if (!String.IsNullOrEmpty(curPath)) {
Debug.LogError("已找到路径:"+ curPath + "\n新发现重复路径:" + fsinfo.FullName);
}
*/
//分割绝对路径FullName,寻找Resource,然后拼接接下来的字符串作为结果
//绝对路径是使用'\'划分,使用转义字符
string[] gets = fsinfo.FullName.Split('\\');
//判定是否找到目标点
bool isFind = false;
for (int i = 0; i < gets.Length; i++) {
if (isFind) {
//拼接
if (name.CompareTo(gets[i])==0) {
//如果拼接时找到目标点,则去除其后缀
string[] end = gets[i].Split('.');
curPath += end[0];
}
else {
//如果拼接时不是目标点,则加个后缀'/'(文件夹没有后缀,不需要分割截取)
curPath += gets[i] + "/";
}
}
//找到拼接起始点(basic_resources = "Resources")
if (gets[i].CompareTo(basic_resources) == 0) {
//在此进行字符串拼接
isFind = true;
}
}//for_end
}
}//foreach_end
return;
}
/// <summary>
/// UI窗口读取
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject Load_UI(string name) {
GameObject prefab = null;
//旧版本
//basic_ui = "ui/";
//string path = basic_ui + "Win_" + name;
//prefab = Resources.Load(path) as GameObject;
//每次寻找前,重置curPath(设置第三个参数为true或手动重置)
director(Application.dataPath+"/Resources/"+ basic_ui, "Win_" + name+".prefab",true);
prefab = Resources.Load(curPath) as GameObject;
if (prefab == null) {
Debug.LogError("Failed UIPrb_Local from " + curPath);
}
return prefab;
}