还在用 Unity 开发游戏?那你就 out 了,试试用 Unity 做一个答题系统吧
 作者:Frank Zhang
- 2022 年 7 月 21 日
- 本文字数:7023 字 - 阅读完需:约 23 分钟 
一、前言
大家都支持 Unity 是用来做游戏开发,比如说做 2D 游戏、3D 游戏,或者工业虚拟仿真软件的开发。
其他 Unity 可以做的有很多,比如答题系统。
本篇就介绍答题系统的开发
这个答题系统,可以从文本文档中提取题目和分数,然后绑定到 UI 上,在答题的过程中,自动判断分数,自动判断正确率。
目的是实现一个可快速导入到项目中使用的小模块。
二、效果图及工程下载
 
 题目文档:https://wwr.lanzoui.com/ihV6nphkzsf密码:47z2
源工程:https://wwr.lanzoui.com/i7wpaphkzuh
三、实现
3-1 界面搭建
首先,新建工程,然后摆 UI,如下图所示:
 
 3-2 读取文档
题目存放在 txt 文档中,首先,我们看一下结构:
 
 每一行都是一道题目,然后题号、题目、选项、得分,都是用冒号进行分割的。
下一步就需要用脚本进行读取文档了。
新建脚本 Answer.cs:编写代码:
读取文档:
using System.Collections.Generic;using UnityEngine;
public class Answer : MonoBehaviour{    //读取文档    string[][] ArrayX;    string[] lineArray;    private int topicMax = 0;//最大题数    private List<bool> isAnserList = new List<bool>();//存放是否答过题的状态
    void Start()    {        TextCsv();    }
    /*****************读取txt数据******************/    void TextCsv()    {        //读取csv二进制文件          TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;        //读取每一行的内容          lineArray = binAsset.text.Split('\r');        //创建二维数组          ArrayX = new string[lineArray.Length][];        //把csv中的数据储存在二维数组中          for (int i = 0; i < lineArray.Length; i++)        {            ArrayX[i] = lineArray[i].Split(':');        }        //查看保存的题目数据        for (int i = 0; i < ArrayX.Length; i++)        {            for (int j = 0; j < ArrayX[i].Length; j++)            {                Debug.Log(ArrayX[i][j]);            }        }        //设置题目状态        topicMax = lineArray.Length;        for (int x = 0; x < topicMax + 1; x++)        {            isAnserList.Add(false);        }    }}
复制代码
 可以看到,所有的题目数据都读取出来了:
 
 3-3 加载题目
using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;
public class Answer : MonoBehaviour{    //读取文档    string[][] ArrayX;//题目数据    string[] lineArray;//读取到题目数据    private int topicMax = 0;//最大题数    private List<bool> isAnserList = new List<bool>();//存放是否答过题的状态
    //加载题目    public GameObject tipsbtn;//提示按钮    public Text tipsText;//提示信息    public List<Toggle> toggleList;//答题Toggle    public Text indexText;//当前第几题    public Text TM_Text;//当前题目    public List<Text> DA_TextList;//选项    private int topicIndex = 0;//第几题
    void Start()    {        TextCsv();        LoadAnswer();    }
    /*****************读取txt数据******************/    void TextCsv()    {        //读取csv二进制文件          TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;        //读取每一行的内容          lineArray = binAsset.text.Split('\r');        //创建二维数组          ArrayX = new string[lineArray.Length][];        //把csv中的数据储存在二维数组中          for (int i = 0; i < lineArray.Length; i++)        {            ArrayX[i] = lineArray[i].Split(':');        }        //设置题目状态        topicMax = lineArray.Length;        for (int x = 0; x < topicMax + 1; x++)        {            isAnserList.Add(false);        }    }
    /*****************加载题目******************/    void LoadAnswer()    {        tipsbtn.SetActive(false);        tipsText.text = "";        for (int x = 0; x < 4; x++)        {            toggleList[x].isOn = false;        }        indexText.text = "第" + (topicIndex + 1) + "题:";//第几题        TM_Text.text = ArrayX[topicIndex][1];//题目        int idx = ArrayX[topicIndex].Length - 3;//有几个选项        for (int x = 0; x < idx; x++)        {            DA_TextList[x].text = ArrayX[topicIndex][x + 2];//选项        }    }}
复制代码
  
 题目正常加载:
 
 3-4 按钮功能
 /*****************按钮功能******************/    void Select_Answer(int index)    {        switch (index)        {            case 0://提示                int idx = ArrayX[topicIndex].Length - 1;                int n = int.Parse(ArrayX[topicIndex][idx]);                string nM = "";                switch (n)                {                    case 1:                        nM = "A";                        break;                    case 2:                        nM = "B";                        break;                    case 3:                        nM = "C";                        break;                    case 4:                        nM = "D";                        break;                }                tipsText.text = "<color=#FFAB08FF>" +"正确答案是:"+ nM + "</color>";                break;            case 1://上一题                if (topicIndex > 0)                {                    topicIndex--;                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "前面已经没有题目了!" + "</color>";                }                break;            case 2://下一题                if (topicIndex < topicMax-1)                {                    topicIndex++;                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "哎呀!已经是最后一题了。" + "</color>";                }                break;            case 3://跳转                int x = int.Parse(jumpInput.text) - 1;                if (x >= 0 && x < topicMax)                {                    topicIndex = x;                    jumpInput.text = "";                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "不在范围内!" + "</color>";                }                break;        }    }
复制代码
 3-5 题目对错判断
/*****************题目对错判断******************/    void AnswerRightRrongJudgment(bool check,int index)    {        if (check)        {            //判断题目对错            bool isRight;            int idx = ArrayX[topicIndex].Length - 1;            int n = int.Parse(ArrayX[topicIndex][idx]) - 1;            if (n == index)            {                tipsText.text = "<color=#27FF02FF>" + "恭喜你,答对了!" + "</color>";                isRight = true;                tipsbtn.SetActive(true);            }            else            {                tipsText.text = "<color=#FF0020FF>" + "对不起,答错了!" + "</color>";                isRight = false;                tipsbtn.SetActive(true);            }
            //正确率计算            if (isAnserList[topicIndex])            {                tipsText.text = "<color=#FF0020FF>" + "这道题已答过!" + "</color>";            }            else            {                anserint++;                if (isRight)                {                    isRightNum++;                }                isAnserList[topicIndex] = true;                TextAccuracy.text = "正确率:" + ((float)isRightNum / anserint * 100).ToString("f2") + "%";            }
            //禁用掉选项            for (int i = 0; i < toggleList.Count; i++)            {                toggleList[i].interactable = false;            }        }    }
复制代码
 将按钮对象拖进卡槽中,运行程序即可:
 
 完整代码如下:
using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;
public class Answer : MonoBehaviour{    //读取文档    string[][] ArrayX;//题目数据    string[] lineArray;//读取到题目数据    private int topicMax = 0;//最大题数    private List<bool> isAnserList = new List<bool>();//存放是否答过题的状态
    //加载题目    public GameObject tipsbtn;//提示按钮    public Text tipsText;//提示信息    public List<Toggle> toggleList;//答题Toggle    public Text indexText;//当前第几题    public Text TM_Text;//当前题目    public List<Text> DA_TextList;//选项    private int topicIndex = 0;//第几题
    //按钮功能及提示信息    public Button BtnBack;//上一题    public Button BtnNext;//下一题    public Button BtnTip;//消息提醒    public Button BtnJump;//跳转题目    public InputField jumpInput;//跳转题目    public Text TextAccuracy;//正确率    private int anserint = 0;//已经答过几题    private int isRightNum = 0;//正确题数
    void Awake()    {        TextCsv();        LoadAnswer();    }
    void Start()    {        toggleList[0].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn,0));        toggleList[1].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn,1));        toggleList[2].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn,2));        toggleList[3].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn,3));
        BtnTip.onClick.AddListener(() => Select_Answer(0));        BtnBack.onClick.AddListener(() => Select_Answer(1));        BtnNext.onClick.AddListener(() => Select_Answer(2));        BtnJump.onClick.AddListener(() => Select_Answer(3));    }
    /*****************读取txt数据******************/    void TextCsv()    {        //读取csv二进制文件          TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;        //读取每一行的内容          lineArray = binAsset.text.Split('\r');        //创建二维数组          ArrayX = new string[lineArray.Length][];        //把csv中的数据储存在二维数组中          for (int i = 0; i < lineArray.Length; i++)        {            ArrayX[i] = lineArray[i].Split(':');        }        //设置题目状态        topicMax = lineArray.Length;        for (int x = 0; x < topicMax + 1; x++)        {            isAnserList.Add(false);        }    }
    /*****************加载题目******************/    void LoadAnswer()    {        for (int i = 0; i < toggleList.Count; i++)        {            toggleList[i].isOn = false;        }        for (int i = 0; i < toggleList.Count; i++)        {            toggleList[i].interactable = true;        }                tipsbtn.SetActive(false);        tipsText.text = "";
        indexText.text = "第" + (topicIndex + 1) + "题:";//第几题        TM_Text.text = ArrayX[topicIndex][1];//题目        int idx = ArrayX[topicIndex].Length - 3;//有几个选项        for (int x = 0; x < idx; x++)        {            DA_TextList[x].text = ArrayX[topicIndex][x + 2];//选项        }    }
    /*****************按钮功能******************/    void Select_Answer(int index)    {        switch (index)        {            case 0://提示                int idx = ArrayX[topicIndex].Length - 1;                int n = int.Parse(ArrayX[topicIndex][idx]);                string nM = "";                switch (n)                {                    case 1:                        nM = "A";                        break;                    case 2:                        nM = "B";                        break;                    case 3:                        nM = "C";                        break;                    case 4:                        nM = "D";                        break;                }                tipsText.text = "<color=#FFAB08FF>" +"正确答案是:"+ nM + "</color>";                break;            case 1://上一题                if (topicIndex > 0)                {                    topicIndex--;                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "前面已经没有题目了!" + "</color>";                }                break;            case 2://下一题                if (topicIndex < topicMax-1)                {                    topicIndex++;                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "哎呀!已经是最后一题了。" + "</color>";                }                break;            case 3://跳转                int x = int.Parse(jumpInput.text) - 1;                if (x >= 0 && x < topicMax)                {                    topicIndex = x;                    jumpInput.text = "";                    LoadAnswer();                }                else                {                    tipsText.text = "<color=#27FF02FF>" + "不在范围内!" + "</color>";                }                break;        }    }
    /*****************题目对错判断******************/    void AnswerRightRrongJudgment(bool check,int index)    {        if (check)        {            //判断题目对错            bool isRight;            int idx = ArrayX[topicIndex].Length - 1;            int n = int.Parse(ArrayX[topicIndex][idx]) - 1;            if (n == index)            {                tipsText.text = "<color=#27FF02FF>" + "恭喜你,答对了!" + "</color>";                isRight = true;                tipsbtn.SetActive(true);            }            else            {                tipsText.text = "<color=#FF0020FF>" + "对不起,答错了!" + "</color>";                isRight = false;                tipsbtn.SetActive(true);            }
            //正确率计算            if (isAnserList[topicIndex])            {                tipsText.text = "<color=#FF0020FF>" + "这道题已答过!" + "</color>";            }            else            {                anserint++;                if (isRight)                {                    isRightNum++;                }                isAnserList[topicIndex] = true;                TextAccuracy.text = "正确率:" + ((float)isRightNum / anserint * 100).ToString("f2") + "%";            }
            //禁用掉选项            for (int i = 0; i < toggleList.Count; i++)            {                toggleList[i].interactable = false;            }        }    }}
复制代码
 四、后言
整体来看,只使用了一个场景,一个脚本,就完成了答题系统。
步骤如下:1、读取文档 2、解析文档保存数据 3、根据数据加载题目 4、上一题下一题,选项选择,跳转,按钮的功能实现
代码还是延期了一贯的简洁风格,希望你可以在这篇文章学到东西。
划线
评论
复制
发布于: 刚刚阅读数: 3
版权声明: 本文为 InfoQ 作者【Frank Zhang】的原创文章。
原文链接:【http://xie.infoq.cn/article/bbd7ded5a4f47b61df1d43c45】。文章转载请联系作者。

Frank Zhang
关注
还未添加个人签名 2019.10.31 加入
还未添加个人简介










 
    
评论