前言:
去年还是小菜鸡的时候分别写过在Unity中单选题和多选题的开发。现在我又有了新的进步,这次可以直接编辑表格,在表格中增删改查数据即可,无需再对代码进行更改! 废话不多说,开始~
首先需要配置两个文件
- 读取表格的程序集:EPPlus
- 处理Json数据的程序集:Newtonsoft.Json
- 表格文件:question.xlsx
大概流程如下
创建StreamingAssets文件
-
首先我们在工程文件Assets文件下创建一个StreamingAssets(这里我们默认使用此路径问加载路径) -
我们在此文件夹下创建一个表格。这里我使用的是.xlsx 下面是表结构,大家如果要修改的话,记得同时修改Question.cs哦!
创建Plugins文件
-
在Assets文件下创建一个名为Plugins文件夹 -
将刚才上面说了两个程序集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";
private void Awake()
{
ReadExcel(quesPackPath, () =>
{
UIQuesPanel.quesList = GetQuesList(package);
questionList = UIQuesPanel.quesList;
});
}
public static ExcelWorkbook ReadExcel(string excelPath, Action action)
{
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;
}
}
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)
{
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()));
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;
public GameObject togPrefab;
public Text analysisTxt;
public Button lastBtn;
public Button nextBtn;
public Button confirmBtn;
public int curQuesIndex = -1;
private void Start()
{
_UIQuesPanelInit();
}
public void OnLastBtnClick()
{
curQuesIndex--;
if (curQuesIndex <0)
{
Debug.LogWarning("前面没有了!");
curQuesIndex = 0;
return;
}
_UpdateQues();
}
public void OnNextBtnClick()
{
curQuesIndex++;
if (curQuesIndex>quesList.Count-1)
{
Debug.LogWarning("后面没有了!");
curQuesIndex = quesList.Count-1;
return;
}
_UpdateQues();
}
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++)
{
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];
}
}
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;
}
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
|