【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明

简介: 【unity小技巧】unity读excel配置表操作,excel转txt文本,并读取txt文本内容,实例说明

前言

关于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代码

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,定义读取配置表类

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,读取不同配置表信息配置

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

调用测试

//初始化配置表
GameConfigManager.Instance.Init();

//测试
string name = GameConfigManager.Instance.GetCardById("1001")["Name"];
print(name);

运行效果,输出正确

读取配置表所有的数据,并使用

比如配置表大概样式

level.xlsx

转换为txt文本后效果

GameConfigManager代码如下

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 调用配置表信息并使用

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();
        }
    }
}

消灭敌人时调用,控制游戏进度变化

GenerateZombies.Instance.ZombieDied(gameObject);

效果

稍后补充

目录
相关文章
|
25天前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
105 5
|
5月前
|
Java BI 数据处理
如何在Java中实现Excel操作
如何在Java中实现Excel操作
|
2月前
|
数据处理 Python
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
这篇文章介绍了如何使用Python读取Excel文件中的数据,处理后将其保存为txt、xlsx和csv格式的文件。
52 3
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
|
6月前
|
Java 数据库 数据安全/隐私保护
Java操作Excel文件导入导出【内含有 jxl.jar 】
Java操作Excel文件导入导出【内含有 jxl.jar 】
84 0
|
4月前
|
存储 测试技术 数据安全/隐私保护
自动化测试小技巧之Airtest-Selenium和Excel的无缝协作
【8月更文挑战第26天】在自动化测试中,Airtest-Selenium 与 Excel 的无缝协作能显著提升测试效率与可维护性。通过将 Excel 作为数据源,可轻松存储和读取测试用例数据;测试结果可自动记录在 Excel 中,便于跟踪与分析;利用 Excel 管理测试用例,简化了用例的增删改查;此外,还能自动截图并记录日志,方便问题定位。这种方式不仅提高了自动化测试的灵活性,还使得测试过程更加透明与高效。
|
4月前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
3月前
|
vr&ar 图形学 API
Unity与VR控制器交互全解:从基础配置到力反馈应用,多角度提升虚拟现实游戏的真实感与沉浸体验大揭秘
【8月更文挑战第31天】虚拟现实(VR)技术迅猛发展,Unity作为主流游戏开发引擎,支持多种VR硬件并提供丰富的API,尤其在VR控制器交互设计上具备高度灵活性。本文详细介绍了如何在Unity中配置VR支持、设置控制器、实现按钮交互及力反馈,结合碰撞检测和物理引擎提升真实感,助力开发者创造沉浸式体验。
169 0
Excel如何使用VBA操作引用其它工作簿中的单元格
Excel引用其它工作簿中的单元格的值及使用VBA操作
|
2月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。