类似于三级背包效果,顶部标题栏,右侧列表栏,中间显示具体哪个标题下的哪个列表按钮所对应的物品信息。
但是所有的数据都是通过读取嵌套文件夹来完成。此时需要一个读取文件夹的工具类。
文件夹列表图:
运行读取文件夹信息生成UI效果图:
注:调用ReadFolderStart(path)时需要传入A文件夹的名字,测试为Assets文件夹下直接传入A,经测试不分大小写,ReadFolderStart(“A”)如果放在Assets文件下的其他文件夹下,举例为Assets/B/A需传入ReadFolderStart(”B/A“)。
因为读取文件首先要获得A文件夹下有多少标题文件夹,所以设置的是开始调用时就自动去获取标题文件夹。我用到的是分步加载数据:第一步点击标题按钮会加载列表按钮信息,记录信息,避免第二次点击时再次加载,因为信息都保存下来,根据标题特有ID存储对应列表,第二次点击时直接打开即可,第二步点击列表按钮,也就是读取A/准确标题文件夹/准确列表文件夹下的物品信息,将信息保存返回,同第一步一样,避免二次加载。因为最后点击物品按钮将生成对应物品,所以代码中有记录名字的集合。
第一次使用www加载方式,因为有return yield 时间会有延时,一旦读取文件后面方法是获得这些图片的信息进行设置,就会出现先获取到的个数是0个,因为此时还没有加载完图片数据,会引发错误。所以这里使用的是IO。
文件夹读取不一定按照你项目中文件夹的排列方式进行读取,如果有文件夹1 文件夹2 文件夹10 读取顺序问 文件夹1 文件夹10文件夹2 所以如果UI上想要按照文件夹的名字来进行加载,文件夹命名要统一,比如01文件夹 02文件夹.. 就会得到想要的效果。
工具类代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
public class ReadFolerSetGameInformation {
List<string> titleName = new List<string>();
Dictionary<int, string> typeName;
Dictionary<int,Texture2D> Tex2D;
Dictionary<int, Dictionary<int, string>> getTypeNameByTitleId = new Dictionary<int, Dictionary<int, string>>();
List<string> TextureToGameObjectPath;
List<string> TextureName;
string fileInfo;
DirectoryInfo[] titleFolderInfo;
DirectoryInfo[] TypeFolderInfo;
FileInfo[] TypeMemberFile;
string TexturePath;
DirectoryInfo dlnfo;
string AFolderPath;
string TitleFolderPath;
string FileName;
string GameObjectLoadingPath;
//根据A路径获取标题文件夹并存取名称
private void GetAllFiles(string fileName = "A")
{
FileName = fileName;
AFolderPath = Application.dataPath + "/" + fileName;
fileInfo = AFolderPath;
dlnfo = new DirectoryInfo(fileInfo);
GetTitleFolder(dlnfo);
}
private List<string> GetTitleFolder(DirectoryInfo dInfo)
{
titleFolderInfo = dInfo.GetDirectories();
for (int i = 0; i < titleFolderInfo.Length; i++)
{
titleName.Add(titleFolderInfo[i].Name.Trim());
}
return titleName;
}
private DirectoryInfo GetTitleFolderInfo(int ID)
{
return titleFolderInfo[ID - 1];
}
//根据传入的标题id,获取对应文件夹下的所有列表文件夹
private Dictionary<int, string> GetTypeFolder(int TitlecurrentId)
{
typeName = new Dictionary<int, string>();
TypeFolderInfo = GetTitleFolderInfo(TitlecurrentId).GetDirectories();
for (int i = 0; i < TypeFolderInfo.Length; i++)
{
typeName.Add(i+1, TypeFolderInfo[i].Name);
}
getTypeNameByTitleId.Add(TitlecurrentId, typeName);
return typeName;
}
//根据点击的具体列表按钮获得此列表对应文件夹的路径 该文件夹在那个列表文件夹下的那个标题文件夹下的路径
private DirectoryInfo BaseTitleIdGetTypeFolderInfo(int titleCurrentId, int typeCurrentId)
{
fileInfo = AFolderPath +("/" +titleName[titleCurrentId - 1] +"/"+ getTypeNameByTitleId[titleCurrentId][typeCurrentId]);
Debug.Log(fileInfo);
dlnfo = new DirectoryInfo(fileInfo);
return dlnfo;
}
private int Num = 0;
private Dictionary<int, Texture2D> GetFile(int titleCurrentId,int typeCurrentId)
{
Tex2D = new Dictionary<int, Texture2D>();
TextureToGameObjectPath = new List<string>();
TextureName = new List<string>();
TypeMemberFile = BaseTitleIdGetTypeFolderInfo(titleCurrentId, typeCurrentId).GetFiles();
for (int i = 0; i < TypeMemberFile.Length; i++)
{
fileInfo = TypeMemberFile[i].Name;
if (!fileInfo.ToString().Contains("meta"))
{
if(fileInfo.ToString().Contains("png"))
{
TextureName.Add(fileInfo);
TexturePath = TypeMemberFile[i].FullName.Trim();
GameObjectLoadingPath = ReturnsObjectPathsByTitleAndList(titleCurrentId, typeCurrentId).Trim()+"/"+ TypeMemberFile[i].Name.Trim();
TextureToGameObjectPath.Add(GameObjectLoadingPath);
LoadByIO(Num + 1 ,TexturePath);
Num++;
}
}
}
Num = 0;
return Tex2D;
}
private string ReturnsObjectPathsByTitleAndList(int titleCurrentId, int typeCurrentId)
{
GameObjectLoadingPath = FileName + ("/" + titleName[titleCurrentId - 1] + "/" + getTypeNameByTitleId[titleCurrentId][typeCurrentId]);
return GameObjectLoadingPath;
}
//IO读取图片
private void LoadByIO(int id, string path)
{
//创建文件流
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
fileStream.Seek(0, SeekOrigin.Begin);
//创建文件长度的缓冲区
byte[] bytes = new byte[fileStream.Length];
//读取文件
fileStream.Read(bytes, 0, (int)fileStream.Length);
//释放文件读取liu
fileStream.Close();
fileStream.Dispose();
fileStream = null;
//创建Texture
int width = 128;
int height = 128;
Texture2D texture2D = new Texture2D(width, height);
texture2D.LoadImage(bytes);
Sprite sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height),
new Vector2(0.5f, 0.5f));
Tex2D.Add(id, sprite.texture);
}
public void ReadFolderStart(string path)
{
GetAllFiles(path);
}
/// <summary>
///根据文件夹获取标题文件夹的名字,可获得标题个数
/// </summary>
/// <returns></returns>
public List<string> GetTitleMemberName()
{
return titleName;
}
/// <summary>
///点击标题,根据点击的标题ID,获取对应列表文件夹返回《列表成员自身ID,列表成员名》
/// </summary>
/// <param name="titleCurrentID"></param>
/// <returns></returns>
public Dictionary<int, string> BasisTitleIdGetTypePanel(int titleCurrentID)
{
return GetTypeFolder(titleCurrentID);
}
/// <summary>
///点击列表成员,根据点击的列表成员ID,获取对应该列表成员文件夹中的图片
/// </summary>
/// <param name="typeCurrentId"></param>
/// <returns></returns>
public Dictionary<int, Texture2D> BasisTypeIDGetViewMemberTex2D(int titleCurrentId ,int typeCurrentId)
{
return GetFile(titleCurrentId,typeCurrentId);
}
/// <summary>
///每个按钮记录自身路径方便加载模型(后缀为.png,字符串要记得截取)
/// </summary>
/// <returns></returns>
public List<string> BasisTypeIDGetViewMenberGameObjectPath()
{
return TextureToGameObjectPath;
}
/// <summary>
/// 每个按钮记录自身名称(后缀为.png,字符串要记得截取)
/// </summary>
/// <returns></returns>
public List<string> BasisTypeIDGetViewMenberGameObjectName()
{
return TextureName;
}
}
判断文件后缀名 方法:
string FilenameExtension;
FilenameExtension = TypeMemberFile[i].Extension;
就能得到文件的后缀名 ".png"".prefab"...
做判断的时候 判断字符串是否相等,如:
if(FilenameExtension == ".png"){
//执行代码....
}