文章目录
前言
关于unity读excel配置表操作,其实之前就有用过,这里只是单独整理出这部分知识,后续好使用。
感兴趣可以去看看:【用unity实现100个游戏之7】从零开始制作一个仿杀戮尖塔卡牌回合制游戏(附项目源码)
下载资源库
读取Excel需要用到
Excel.dll
和ICSharpCode.SharpZipLib
库文件
这里我把两个库都放在百度云了,大家可以自行去下载
链接:https://pan.baidu.com/s/1iM-E5TSAxtlWOAhMmWy1ZQ?pwd=s8o4
提取码:s8o4
导入资源库
将前面下载的这两个dll库放进项目即可
excel转txt文本
新建MyEditor.cs放在Editor
目录下
MyEditor.cs代码
csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;//编辑器的命名空间
using System.IO;//文件流
using Excel;//读取excel
using System.Data;
//编辑器脚本
public static class MyEditor
{
[MenuItem("我的工具/excel转成txt")]
public static void ExportExcelToTxt()
{
//_Excel文件夹路径
string assetPath = Application.dataPath + "/_Excel";
//获得Excel文件夹中的excel文件
string[] files = Directory.GetFiles(assetPath, "*.xlsx");
for (int i = 0; i < files.Length; i++)
{
files[i] = files[i].Replace('\\', '/');//反斜杠替换成正斜杠
//通过文件流读取文件
using (FileStream fs = File.Open(files[i], FileMode.Open, FileAccess.Read))
{
//文件流转成excel 对象
var excelDataReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
//获得excel数据
DataSet dataSet = excelDataReader.AsDataSet();
//读取excel第一张表
DataTable table = dataSet.Tables[0];
//将表中内容 读取后 存储到 对应的txt文件
readTableToTxt(files[i], table);
}
}
//刷新编辑器
AssetDatabase.Refresh();
}
private static void readTableToTxt(string filePath, DataTable table)
{
// 获得文件名(不要文件后缀 生成与之名字相同的txt文件)
string fileName = Path.GetFileNameWithoutExtension(filePath);
// txt文件存储的路径
string path = Application.dataPath + "/Resources/Data/" + fileName + ".txt";
//判断Resources/Data文件夹中是否已经存在对应的txt文件,如果是 则删除
if (File.Exists(path))
{
File.Delete(path);
}
// 文件流创建txt文件
using (FileStream fs = new FileStream(path, FileMode.Create))
{
// 文件流转写入流方便写入字符串
using (StreamWriter sw = new StreamWriter(fs))
{
// 遍历table
for (int row = 0; row < table.Rows.Count; row++)
{
DataRow dataRow = table.Rows[row];
string str = "";
//遍历列
for (int col = 0; col < table.Columns.Count; col++)
{
string val = dataRow[col].ToString();
str = str + val + "\t";//每一项tab分割
}
//写入
sw.Write(str);
//如果不是最后一行换行
if (row != table.Rows.Count - 1)
{
sw.WriteLine();
}
}
}
}
}
}
记得在Resources目录下新建Data文件夹用来存放生成的txt文本,我们的xlsx配置表信息就放在_Excel文件夹下,点击我的工具->excel转成txt
,会将_Excel文件夹里的xlsx文件生成为txt保存到/Resources/Data/目录下
配置表大概样式
card.xlsx
转为txt后内容如下
读取txt内容
新增GameConfigData,定义读取配置表类
csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 游戏配置表类,每个对象对应一个xt配置表
public class GameConfigData
{
// 存储配置表中的所有数据
private List<Dictionary<string, string>> dataDic;
// 构造函数,参数为字符串
public GameConfigData(string str)
{
// 初始化数据字典
dataDic = new List<Dictionary<string, string>>();
// 按换行符切割字符串
string[] lines = str.Split('\n');
// 第一行是存储数据的类型
string[] title = lines[0].Trim().Split('\t');//tab切割
// 从第三行(下标为2)开始遍历数据,第二行数据是解释说明
for (int i = 2; i < lines.Length; i++)
{
// 创建新的字典存储每行数据
Dictionary<string, string> dic = new Dictionary<string, string>();
// 按tab切割每行数据
string[] tempArr = lines[i].Trim().Split("\t");
// 将切割后的数据添加到字典中
for (int j = 0; j < tempArr.Length; j++)
{
dic.Add(title[j], tempArr[j]);
}
// 将字典添加到数据列表中
dataDic.Add(dic);
}
}
// 获取所有行的数据
public List<Dictionary<string, string>> GetLines()
{
return dataDic;
}
// 根据ID获取一行数据
public Dictionary<string, string> GetOneById(string id)
{
// 遍历数据列表
for (int i = 0; i < dataDic.Count; i++)
{
// 获取当前字典
Dictionary<string, string> dic = dataDic[i];
// 如果字典中的ID与参数相同,返回该字典
if (dic["Id"] == id)
{
return dic;
}
}
// 如果没有找到,返回null
return null;
}
}
新增GameConfigManager.cs,读取不同配置表信息配置
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
// 游戏配置管理类
public class GameConfigManager
{
// 单例模式
public static GameConfigManager Instance = new GameConfigManager();
private GameConfigData cardData;//卡牌表
private GameConfigData enemyData;//敌人表
private GameConfigData levelData;//关卡表
private GameConfigData cardTypeData; //卡牌类型
// 文本资源
private TextAsset textAsset;
// 初始化配置文件(txt文件 存储到内存)
public void Init()
{
// 加载卡牌数据
textAsset = Resources.Load<TextAsset>("Data/card");
cardData = new GameConfigData(textAsset.text);
// 加载敌人数据
textAsset = Resources.Load<TextAsset>("Data/enemy");
enemyData = new GameConfigData(textAsset.text);
// 加载关卡数据
textAsset = Resources.Load<TextAsset>("Data/level");
levelData = new GameConfigData(textAsset.text);
//卡牌类型数据
textAsset = Resources.Load<TextAsset>("Data/cardType");
cardTypeData = new GameConfigData(textAsset.text);
}
// 获取卡牌行数据
public List<Dictionary<string, string>> GetCardLines()
{
return cardData.GetLines();
}
// 获取敌人行数据
public List<Dictionary<string, string>> GetEnemyLines()
{
return enemyData.GetLines();
}
// 获取关卡行数据
public List<Dictionary<string, string>> GetLevelLines()
{
return levelData.GetLines();
}
// 根据ID获取卡牌数据
public Dictionary<string, string> GetCardById(string id)
{
return cardData.GetOneById(id);
}
// 根据ID获取敌人数据
public Dictionary<string, string> GetEnemyById(string id)
{
return enemyData.GetOneById(id);
}
// 根据ID获取关卡数据
public Dictionary<string, string> GetLevelById(string id)
{
return levelData.GetOneById(id);
}
//根据ID获取卡牌类型
public Dictionary<string, string> GetCardTypeById(string id)
{
return cardTypeData.GetOneById(id);
}
}
调用测试
csharp
//初始化配置表
GameConfigManager.Instance.Init();
//测试
string name = GameConfigManager.Instance.GetCardById("1001")["Name"];
print(name);
运行效果,输出正确
读取配置表所有的数据,并使用
比如配置表大概样式
level.xlsx
转换为txt文本后效果
GameConfigManager代码如下
sql
using System.Collections.Generic;
using UnityEngine;
// 游戏配置管理类
public class GameConfigManager
{
public static GameConfigManager Instance = new GameConfigManager();
private GameConfigData levelData;//关卡数据
// 文本资源
private TextAsset textAsset;
// 初始化配置文件(txt文件 存储到内存)
public void Init()
{
// 加载关卡数据
textAsset = Resources.Load<TextAsset>("Data/level");
levelData = new GameConfigData(textAsset.text);
}
// 获取关卡行数据
public List<Dictionary<string, string>> GetLevelLines()
{
return levelData.GetLines();
}
// 根据ID获取关卡数据
public Dictionary<string, string> GetLevelById(string id)
{
return levelData.GetOneById(id);
}
}
新增GenerateZombies 调用配置表信息并使用
sql
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using Unity.VisualScripting;
using UnityEngine;
public class GenerateZombies : MonoBehaviour
{
public static GenerateZombies Instance { get; private set; }
public GameObject zombiePrefab; //僵尸预制体
public int curLevelId = 1; //当前关卡
public int curProgressId = 1;//当前进度
public List<GameObject> curProgressZombie;//保存当前进度的敌人
int zOrderIndex = 0;//排序
private void Awake()
{
Instance = this;
}
private void Start()
{
curProgressZombie = new List<GameObject>();
//初始化配置表
GameConfigManager.Instance.Init();
TableCreateZombie();
}
//生成僵尸
private void TableCreateZombie()
{
//判断是否是最后一波敌人,如果表格中当前进度没有可以创建的敌人,及游戏胜利
bool canCreate = false;
//获取关卡行数据
List<Dictionary<string, string>> listData = GameConfigManager.Instance.GetEnemyLines();
listData.ForEach(data =>
{
//属于当前关卡的僵尸
if (data["levelID"] == curLevelId.ToString() && data["progressId"] == curProgressId.ToString())
{
//延迟一段时间创建僵尸
StartCoroutine(ITableCreateZombie(data));
//代表当前进度有敌人
canCreate = true;
}
});
if(!canCreate){
StopAllCoroutines();//停止所有的携程
//TODO:游戏胜利处理
Debug.Log("游戏胜利");
}
}
IEnumerator ITableCreateZombie(Dictionary<string, string> levelItem)
{
yield return new WaitForSeconds(float.Parse(levelItem["createTime"]));
//加载预制件:从Resources文件夹中加载,例如Zombie1
GameObject zombiePrefab = Resources.Load("Prefabs/Zombie" + levelItem["zombieType"]) as GameObject;
//生成僵尸实例
GameObject zombie = Instantiate(zombiePrefab);
//根据配表的生成位置,找到父物体
Transform zombieLine = transform.GetChild(int.Parse(levelItem["bornPos"]));
zombie.transform.parent = zombieLine;
zombie.transform.localPosition = Vector3.zero;
zombie.GetComponent<SpriteRenderer>().sortingOrder = zOrderIndex;
zOrderIndex ++;
curProgressZombie.Add(zombie);
}
//消灭敌人
public void ZombieDied(GameObject gameObject){
if(curProgressZombie.Contains(gameObject)){
curProgressZombie.Remove(gameObject);
}
//当前进度的僵尸全部消灭了,开启下一个进度
if(curProgressZombie.Count == 0){
curProgressId += 1;
TableCreateZombie();
}
}
}
消灭敌人时调用,控制游戏进度变化
sql
GenerateZombies.Instance.ZombieDied(gameObject);
效果
稍后补充
结束语
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~