前言:

去年还是小菜鸡的我写过在Unity中单选题和多选题的开发。现在进步一点点,这次可以直接编辑表格,在表格中增删改查数据即可,无需再对代码进行更改!
下载链接在文章末尾,需要的可以直接划到最后!

废话不多说,开始~

首先需要配置三个文件

  1. 读取表格的程序集:EPPlus
  2. 处理Json数据的程序集:Newtonsoft.Json
  3. 表格文件:question.xlsx

大概流程如下

创建StreamingAssets文件

  1. 首先我们在工程文件Assets文件下创建一个StreamingAssets(这里我们默认使用此路径为加载路径)

  2. 我们在此文件夹下创建一个表格。这里我使用的是.xlsx
    下面是表结构,大家如果要修改的话,记得同时修改Question.cs哦!

创建Plugins文件

  1. 在Assets文件下创建一个名为Plugins文件夹

  2. 将刚才上面说了两个程序集EPPlus和Newtonsoft.Json放入此文件下

做完上面那些就可以导入我给大伙准备的脚本了

这里一共有三个脚本:

  • ExcelMgr.cs
  • Question.cs
  • UIQuesPanel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OfficeOpenXml;
using System.IO;
using System.Data;
using System;
using Newtonsoft.Json.Linq;
using DialogEntity;namespace vvb_ExcelMgr
{public class ExcelMgr : MonoBehaviour{static ExcelPackage package;//表文件缓存public static ExcelWorkbook dialogWorkbook;//表工作簿public List<Question> questionList = new List<Question>();//题目缓存列表public string quesPackPath="question";//题目文件地址,文件后缀默认为".xlsx"private void Awake(){ReadExcel(quesPackPath, () =>{UIQuesPanel.quesList = GetQuesList(package);questionList = UIQuesPanel.quesList;//这里为了在inspecter中能看到读取到达数据});}/// <summary>/// 打开表缓存/// </summary>public static ExcelWorkbook ReadExcel(string excelPath, Action action){//Debug.Log(Application.streamingAssetsPath);excelPath = Application.streamingAssetsPath + "/"+excelPath+".xlsx";try{using (package = new ExcelPackage(new FileStream(excelPath, FileMode.Open))){action?.Invoke();return package.Workbook;}}catch (NullReferenceException e){Debug.LogError("空指针异常:" + e);return null;}catch (IOException e){Debug.LogError("文件打开异常:" + e);return null;}catch (Exception e){Debug.LogError("其他异常:" + e);return null;}}public List<Question> GetQuesList(ExcelPackage excelPackage){List<Question> quesList = new List<Question>();int dataStartRow = 0;if (excelPackage.Workbook.Worksheets.Count < 0){Debug.LogError("空表");return null;}ExcelWorksheet sheet = excelPackage.Workbook.Worksheets[1];for (int startRow = sheet.Dimension.Start.Row, endRow = sheet.Dimension.End.Row; startRow <= endRow; startRow++){if (sheet.GetValue(startRow, 1).ToString().Equals("quesId"))//此行开始才是咱们真正需要的数据,当然在开发过程中这里是不需要的{dataStartRow = startRow;break;}//Debug.Log(sheet.GetValue(startRow, 1).ToString());//Debug.Log(sheet.GetValue(2, 1).ToString());}for (int startRow = dataStartRow+1, endRow = sheet.Dimension.End.Row; startRow <= endRow; startRow++){JObject question = new JObject();//每一行实例化一个对象,用来存储到题目列表中for (int startColumn = sheet.Dimension.Start.Column, endColumn = sheet.Dimension.End.Column; startColumn <= endColumn; startColumn++){//这里要注意做一步特殊处理,因为当读取到选项内容那一行时,类型为数组,所以我们需要特殊处理一下if (startColumn == 3)//在表中我们将选项内容放在C列,也就是第三项。或者各位也可以使用其他的方式判定{JArray options = new JArray();string[] opsStr = sheet.GetValue(startRow, startColumn).ToString().Split(';');//这里先获取此处的字符串,然后再使用我们自定的符号切割以获得选项数组options.Add(opsStr);question.Add(sheet.GetValue(dataStartRow, startColumn).ToString(), options);}else{question.Add(sheet.GetValue(dataStartRow, startColumn).ToString(), sheet.GetValue(startRow, startColumn).ToString());}}quesList.Add(JsonUtility.FromJson<Question>(question.ToString()));//转成Question对象添加入列表中Debug.Log(question);}return quesList;}}
}
using System;
[Serializable]
public class Question
{public int quesId;//当前题号public string tittleStr;//题目内容public string[] optionsStr;//选项内容public int quesType;//题目类型public string ans;//正确答案public string analysis;//解析public int nextQuesId;//下一题号
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class UIQuesPanel : MonoBehaviour
{//为了方便,所有变量均拖拽赋值。public static List<Question> quesList = new List<Question>();public Text tittleTxt;//题目内容public RectTransform optionsRoot;//选项生成根节点public List<Toggle> optionTogList;//选项public ToggleGroup toggleGroup;//根节点togglegroup组件public GameObject togPrefab;//选项预制体public Text analysisTxt;//解析文本public Button lastBtn;//上一题按钮public Button nextBtn;//下一题按钮public Button confirmBtn;//确认作答按钮public int curQuesIndex = -1;//当前题索引private void Start(){_UIQuesPanelInit();}/// <summary>/// 上一题/// </summary>public void OnLastBtnClick(){curQuesIndex--;if (curQuesIndex <0){Debug.LogWarning("前面没有了!");curQuesIndex = 0;return;}_UpdateQues();}/// <summary>/// 下一题/// </summary>public void OnNextBtnClick()//这里加载下一题的方式也可以通过表中的字段nextQuesId,上一题同理(表中暂未设计)。{curQuesIndex++;if (curQuesIndex>quesList.Count-1){Debug.LogWarning("后面没有了!");curQuesIndex = quesList.Count-1;return;}_UpdateQues();}/// <summary>/// 刷新题目/// </summary>private void _UpdateQues(){analysisTxt.gameObject.SetActive(false);tittleTxt.text = (curQuesIndex + 1).ToString() + "." + quesList[curQuesIndex].tittleStr;int optionsCount = optionsRoot.childCount;optionTogList.Clear();while (optionsCount > 0){optionsCount--;Destroy(optionsRoot.GetChild(optionsCount).gameObject);}for (int i = 0; i < quesList[curQuesIndex].optionsStr.Length; i++)//根据选项个数创建相应的toggle数量{optionTogList.Add(Instantiate(togPrefab, optionsRoot).GetComponent<Toggle>());optionTogList[i].isOn = false;if (quesList[curQuesIndex].quesType == 0){optionTogList[i].group = toggleGroup;}optionTogList[i].GetComponentInChildren<Text>().text = quesList[curQuesIndex].optionsStr[i];}}/// <summary>/// 确认作答/// </summary>public void OnConfirmBtnClick(){if (curQuesIndex<0||curQuesIndex>quesList.Count-1){Debug.LogError("数组越界");return;}string selected=null;//用户选择analysisTxt.text = selected;analysisTxt.gameObject.SetActive(true);switch (quesList[curQuesIndex].quesType){case 0://单选for (int i = 0; i < optionTogList.Count; i++){if (optionTogList[i].isOn){selected = optionTogList[i].GetComponentInChildren<Text>().text[0].ToString();//默认第一个字符代表此选项,并与答案进行对比。这里正误判定也可以自己定义Debug.Log("选择的答案为:" + selected);break;}}break;case 1://多选for (int i = 0; i < optionTogList.Count; i++){if (optionTogList[i].isOn){selected += optionTogList[i].GetComponentInChildren<Text>().text[0].ToString();}}break;default:break;}if (string.IsNullOrEmpty(selected))//没作答情况。具体可以自定义,比如你弹出一个面板提示什么的,强制答完才行。{selected = "未作答";Debug.LogError("请先选择选项!");}if (selected.Equals(quesList[curQuesIndex].ans))//与正确答案做比较{Debug.Log("正确");analysisTxt.text = "<color=green>回答正确</color>   ";}else{Debug.Log("错误");analysisTxt.text = "<color=red>回答错误</color>   ";}analysisTxt.text += "你的答案:" + selected + "   正确答案:" + quesList[curQuesIndex].ans+"\n解析:" + quesList[curQuesIndex].analysis;}/// <summary>/// 面板初始化/// </summary>private void _UIQuesPanelInit(){//这里大伙儿可以自己默认调用一次“下一题”按钮的事件来默认更新第一道题。我就不写了analysisTxt.gameObject.SetActive(false);if (optionsRoot.gameObject.GetComponent<ToggleGroup>()){toggleGroup = optionsRoot.gameObject.GetComponent<ToggleGroup>();}else{toggleGroup = optionsRoot.gameObject.AddComponent<ToggleGroup>();}toggleGroup.allowSwitchOff = true;}
}

具体的过程我就不详述了,大伙儿看代码自行体会!

有何疑问欢迎留言讨论!需要源码的可以评论区留言或者私聊。

下面是源工程的下载地址:
链接:https://pan.baidu.com/s/1hrmtq9PGJlDg4Ya_YO6FeQ
提取码:grnh

在Unity中使用Excel表开发单选题和多选题相关推荐

  1. unity中解析excel表

    上代码 using Excel; using System; using System.Collections; using System.Collections.Generic; using Sys ...

  2. vba mysql·教程_Excel VBA ADO SQL入门教程004:SQL中的Excel表

    1. 上期我们聊了SQL常用查询语句中的字段查询,其简化版语法如下: SELECT 字段名 FROM 表名 当时我们说,FROM关键词指明了要获取字段信息的表的名称.倘若数据源是Excel表格,则需要 ...

  3. [Java中实现Excel表导入导出]基于easy-poi和EasyExcel两种方式实现

    第一种:基于easy-poi实现Excel导入导出 1.导出Excel表格 第一步:在pom文件中导入依赖 <!--基于easy-poi实现Excel导入导出--><dependen ...

  4. Unity 中配置文件Excel 转xml ;josn;序列化ScriptableObject及加载(最详细)。

    游戏中对策划的配置数据导入处理常用分为1.转xml或josn.2.序列化为ScriptableObject类.第一种方法游戏加载耗时一些,第二种避免了第一种方法加载缺点但内存要占用大一些.不过推荐第二 ...

  5. Unity中对Excel的操作(使用EPPlus)

    目录 一.导入EPPlus 1.首先在Unity中导入EPPlus和Excel 2.创建脚本,引入命名空间​​​​​​​ 二.读取Excel 1. 获取Excel信息文件 2.打开Excel文件信息, ...

  6. django项目中实现excel表数据导入

    依赖模块: xlrd模块安装:pip install xlrd 安装好xlrd模块之后基本的准备工作就已经完成. 实现: views.py: def import_excel(self, reques ...

  7. java代码中实现excel表下载

    我这边定义了一个类Excel,然后定义了一个初始化方法 public class Ecxel {     public static HSSFFont font; public static HSSF ...

  8. vue导入excel进度条_在vue中导入Excel表

    使用的库js-xlsx 纯JS即可读取和导出excel的工具库https://github.com/SheetJS/js-xlsx 安装 直接下载dist目录下有很多个JS文件,一般情况下用xlsx. ...

  9. 将PPT中的excel表变成柱状图

    如下表和图所示,那个更立体形象呢? 答案不言而喻. 第一步,做数据表 第二步,插入[图表] 点击确定后,会出现如下图: 你需要将前一页做的数据表,复制,粘贴到这个柱状图excel中 选择[匹配目标格式 ...

最新文章

  1. Spring_boot_pom.xml和启动方式
  2. 3 年经验的 Java 后端妹子,横扫阿里、滴滴、美团,整理出这份厚厚的 8000 字面经!...
  3. 老师吴恩达,身家又增20亿
  4. 开发日记-20190607 关键词 读书笔记《鸟哥的Linux私房菜-基础学习篇》
  5. 社交游戏纳入文化部监管视野 开发者或出海
  6. Java数据类型与各数据库类型对应一览表
  7. fzyzojP2291 -- 小添添的庄园之道路修复
  8. linux gfs原理,Linux GFS 配置方法及注意事项
  9. ruby学习笔记(3)--语法层面的先见之明
  10. Python 命令行之旅:深入 argparse(二)
  11. 协同多智能体学习的价值分解网络的原理与代码复现
  12. 3步教你学会cocos creator 物理引擎
  13. 10月最新720全景云系统,可生成小程序+带PC端+安装教程
  14. 使用ssh登录华为云linux,mac远程ssh登陆华为云--linux版本
  15. php fpm failed,ubuntu环境下启动php-fpm失败Job for php-fpm.service failed...
  16. AVplayer断网播放出错时player的duration、playableDuration、totalTime
  17. aws上创建eks集群
  18. CentOS7基于Hadoop 2.7.3安装Hive 2.1.1
  19. vue2 对接网易im初始化操作
  20. flash游戏地图编辑器

热门文章

  1. 大一高级计算机考试内容,大一计算机考试内容
  2. Crash自动修复系统
  3. 阿里云 windows 服务器卸载阿里云盾
  4. Spring Boot 2.2.x Junit4 升级为Junit5 后的变化、对比 找不到 org.junit.jupiter.api.Test
  5. HDMI接口的HPD问题
  6. phpadmin安装到mysql中,mysql 和phpadmin安装
  7. 最牛叉的街机游戏合集 模拟器
  8. Cosine Similarity 与 L2distanse
  9. Android UI自动化工具-SoloPi
  10. 基于Syntiant TinyML Board与Edge Impulse的LED语音控制(Arduino/C++)