Unity3D實(shí)戰(zhàn)之答題系統(tǒng)的實(shí)現(xiàn)
一、前言
這是本專欄系列的第一篇,答題系統(tǒng)的開發(fā)。
這個(gè)答題系統(tǒng),可以從文本文檔中提取題目和分?jǐn)?shù),然后綁定到UI上,在答題的過程中,自動(dòng)判斷分?jǐn)?shù),自動(dòng)判斷正確率。
目的是實(shí)現(xiàn)一個(gè)可快速導(dǎo)入到項(xiàng)目中使用的小模塊。
二、效果圖及工程下載

題目文檔 密碼:1234
三、實(shí)現(xiàn)
1.界面搭建
首先,新建工程,然后擺UI,如下圖所示:

2.讀取文檔
題目存放在txt文檔中,首先,我們看一下結(jié)構(gòu):

每一行都是一道題目,然后題號(hào)、題目、選項(xiàng)、得分,都是用冒號(hào)進(jìn)行分割的。
下一步就需要用腳本進(jìn)行讀取文檔了。
新建腳本Answer.cs:編寫代碼:
讀取文檔:
using System.Collections.Generic;
using UnityEngine;
public class Answer : MonoBehaviour
{
//讀取文檔
string[][] ArrayX;
string[] lineArray;
private int topicMax = 0;//最大題數(shù)
private List<bool> isAnserList = new List<bool>();//存放是否答過題的狀態(tài)
void Start()
{
TextCsv();
}
/*****************讀取txt數(shù)據(jù)******************/
void TextCsv()
{
//讀取csv二進(jìn)制文件
TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;
//讀取每一行的內(nèi)容
lineArray = binAsset.text.Split('\r');
//創(chuàng)建二維數(shù)組
ArrayX = new string[lineArray.Length][];
//把csv中的數(shù)據(jù)儲(chǔ)存在二維數(shù)組中
for (int i = 0; i < lineArray.Length; i++)
{
ArrayX[i] = lineArray[i].Split(':');
}
//查看保存的題目數(shù)據(jù)
for (int i = 0; i < ArrayX.Length; i++)
{
for (int j = 0; j < ArrayX[i].Length; j++)
{
Debug.Log(ArrayX[i][j]);
}
}
//設(shè)置題目狀態(tài)
topicMax = lineArray.Length;
for (int x = 0; x < topicMax + 1; x++)
{
isAnserList.Add(false);
}
}
}
可以看到,所有的題目數(shù)據(jù)都讀取出來了:

3.加載題目
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Answer : MonoBehaviour
{
//讀取文檔
string[][] ArrayX;//題目數(shù)據(jù)
string[] lineArray;//讀取到題目數(shù)據(jù)
private int topicMax = 0;//最大題數(shù)
private List<bool> isAnserList = new List<bool>();//存放是否答過題的狀態(tài)
//加載題目
public GameObject tipsbtn;//提示按鈕
public Text tipsText;//提示信息
public List<Toggle> toggleList;//答題Toggle
public Text indexText;//當(dāng)前第幾題
public Text TM_Text;//當(dāng)前題目
public List<Text> DA_TextList;//選項(xiàng)
private int topicIndex = 0;//第幾題
void Start()
{
TextCsv();
LoadAnswer();
}
/*****************讀取txt數(shù)據(jù)******************/
void TextCsv()
{
//讀取csv二進(jìn)制文件
TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;
//讀取每一行的內(nèi)容
lineArray = binAsset.text.Split('\r');
//創(chuàng)建二維數(shù)組
ArrayX = new string[lineArray.Length][];
//把csv中的數(shù)據(jù)儲(chǔ)存在二維數(shù)組中
for (int i = 0; i < lineArray.Length; i++)
{
ArrayX[i] = lineArray[i].Split(':');
}
//設(shè)置題目狀態(tài)
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;//有幾個(gè)選項(xiàng)
for (int x = 0; x < idx; x++)
{
DA_TextList[x].text = ArrayX[topicIndex][x + 2];//選項(xiàng)
}
}
}

題目正常加載:

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>" + "前面已經(jīng)沒有題目了!" + "</color>";
}
break;
case 2://下一題
if (topicIndex < topicMax-1)
{
topicIndex++;
LoadAnswer();
}
else
{
tipsText.text = "<color=#27FF02FF>" + "哎呀!已經(jīng)是最后一題了。" + "</color>";
}
break;
case 3://跳轉(zhuǎn)
int x = int.Parse(jumpInput.text) - 1;
if (x >= 0 && x < topicMax)
{
topicIndex = x;
jumpInput.text = "";
LoadAnswer();
}
else
{
tipsText.text = "<color=#27FF02FF>" + "不在范圍內(nèi)!" + "</color>";
}
break;
}
}5.題目對(duì)錯(cuò)判斷
/*****************題目對(duì)錯(cuò)判斷******************/
void AnswerRightRrongJudgment(bool check,int index)
{
if (check)
{
//判斷題目對(duì)錯(cuò)
bool isRight;
int idx = ArrayX[topicIndex].Length - 1;
int n = int.Parse(ArrayX[topicIndex][idx]) - 1;
if (n == index)
{
tipsText.text = "<color=#27FF02FF>" + "恭喜你,答對(duì)了!" + "</color>";
isRight = true;
tipsbtn.SetActive(true);
}
else
{
tipsText.text = "<color=#FF0020FF>" + "對(duì)不起,答錯(cuò)了!" + "</color>";
isRight = false;
tipsbtn.SetActive(true);
}
//正確率計(jì)算
if (isAnserList[topicIndex])
{
tipsText.text = "<color=#FF0020FF>" + "這道題已答過!" + "</color>";
}
else
{
anserint++;
if (isRight)
{
isRightNum++;
}
isAnserList[topicIndex] = true;
TextAccuracy.text = "正確率:" + ((float)isRightNum / anserint * 100).ToString("f2") + "%";
}
//禁用掉選項(xiàng)
for (int i = 0; i < toggleList.Count; i++)
{
toggleList[i].interactable = false;
}
}
}
將按鈕對(duì)象拖進(jìn)卡槽中,運(yùn)行程序即可:

完整代碼如下:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Answer : MonoBehaviour
{
//讀取文檔
string[][] ArrayX;//題目數(shù)據(jù)
string[] lineArray;//讀取到題目數(shù)據(jù)
private int topicMax = 0;//最大題數(shù)
private List<bool> isAnserList = new List<bool>();//存放是否答過題的狀態(tài)
//加載題目
public GameObject tipsbtn;//提示按鈕
public Text tipsText;//提示信息
public List<Toggle> toggleList;//答題Toggle
public Text indexText;//當(dāng)前第幾題
public Text TM_Text;//當(dāng)前題目
public List<Text> DA_TextList;//選項(xiàng)
private int topicIndex = 0;//第幾題
//按鈕功能及提示信息
public Button BtnBack;//上一題
public Button BtnNext;//下一題
public Button BtnTip;//消息提醒
public Button BtnJump;//跳轉(zhuǎn)題目
public InputField jumpInput;//跳轉(zhuǎn)題目
public Text TextAccuracy;//正確率
private int anserint = 0;//已經(jīng)答過幾題
private int isRightNum = 0;//正確題數(shù)
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數(shù)據(jù)******************/
void TextCsv()
{
//讀取csv二進(jìn)制文件
TextAsset binAsset = Resources.Load("YW", typeof(TextAsset)) as TextAsset;
//讀取每一行的內(nèi)容
lineArray = binAsset.text.Split('\r');
//創(chuàng)建二維數(shù)組
ArrayX = new string[lineArray.Length][];
//把csv中的數(shù)據(jù)儲(chǔ)存在二維數(shù)組中
for (int i = 0; i < lineArray.Length; i++)
{
ArrayX[i] = lineArray[i].Split(':');
}
//設(shè)置題目狀態(tài)
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;//有幾個(gè)選項(xiàng)
for (int x = 0; x < idx; x++)
{
DA_TextList[x].text = ArrayX[topicIndex][x + 2];//選項(xiàng)
}
}
/*****************按鈕功能******************/
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>" + "前面已經(jīng)沒有題目了!" + "</color>";
}
break;
case 2://下一題
if (topicIndex < topicMax-1)
{
topicIndex++;
LoadAnswer();
}
else
{
tipsText.text = "<color=#27FF02FF>" + "哎呀!已經(jīng)是最后一題了。" + "</color>";
}
break;
case 3://跳轉(zhuǎn)
int x = int.Parse(jumpInput.text) - 1;
if (x >= 0 && x < topicMax)
{
topicIndex = x;
jumpInput.text = "";
LoadAnswer();
}
else
{
tipsText.text = "<color=#27FF02FF>" + "不在范圍內(nèi)!" + "</color>";
}
break;
}
}
/*****************題目對(duì)錯(cuò)判斷******************/
void AnswerRightRrongJudgment(bool check,int index)
{
if (check)
{
//判斷題目對(duì)錯(cuò)
bool isRight;
int idx = ArrayX[topicIndex].Length - 1;
int n = int.Parse(ArrayX[topicIndex][idx]) - 1;
if (n == index)
{
tipsText.text = "<color=#27FF02FF>" + "恭喜你,答對(duì)了!" + "</color>";
isRight = true;
tipsbtn.SetActive(true);
}
else
{
tipsText.text = "<color=#FF0020FF>" + "對(duì)不起,答錯(cuò)了!" + "</color>";
isRight = false;
tipsbtn.SetActive(true);
}
//正確率計(jì)算
if (isAnserList[topicIndex])
{
tipsText.text = "<color=#FF0020FF>" + "這道題已答過!" + "</color>";
}
else
{
anserint++;
if (isRight)
{
isRightNum++;
}
isAnserList[topicIndex] = true;
TextAccuracy.text = "正確率:" + ((float)isRightNum / anserint * 100).ToString("f2") + "%";
}
//禁用掉選項(xiàng)
for (int i = 0; i < toggleList.Count; i++)
{
toggleList[i].interactable = false;
}
}
}
}
四、后言
整體來看,只使用了一個(gè)場(chǎng)景,一個(gè)腳本,就完成了答題系統(tǒng)。
步驟如下:
1、讀取文檔
2、解析文檔保存數(shù)據(jù)
3、根據(jù)數(shù)據(jù)加載題目
4、上一題下一題,選項(xiàng)選擇,跳轉(zhuǎn),按鈕的功能實(shí)現(xiàn)
代碼還是延期了一貫的簡(jiǎn)潔風(fēng)格,希望你可以在這篇文章學(xué)到東西。
以上就是Unity3D實(shí)戰(zhàn)之答題系統(tǒng)的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Unity3D答題系統(tǒng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#利用File方法對(duì)文件的操作總結(jié)(字節(jié)寫入和讀?。?/a>
使用C#語言中的File類我們能夠非常輕松的使用一些文件操作的函數(shù)來完成對(duì)文件簡(jiǎn)單的讀寫操作,這篇文章主要給大家介紹了光宇C#利用File方法對(duì)文件的操作的相關(guān)資料,包括字節(jié)寫入和讀取,需要的朋友可以參考下2021-08-08
C#導(dǎo)出網(wǎng)站功能實(shí)例代碼講解
這篇文章主要介紹了C#導(dǎo)出網(wǎng)站功能實(shí)例代碼,需要的朋友可以參考下2015-10-10
C#多線程處理多個(gè)隊(duì)列數(shù)據(jù)的方法
本文將結(jié)合實(shí)例代碼,介紹C#多線程處理多個(gè)隊(duì)列數(shù)據(jù)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
unity 如何獲取Text組件里text內(nèi)容的長(zhǎng)度
這篇文章主要介紹了unity 獲取Text組件里text內(nèi)容的長(zhǎng)度操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04
C#使用Twain協(xié)議實(shí)現(xiàn)掃描儀連續(xù)掃描功能
這篇文章主要介紹了C#使用Twain協(xié)議實(shí)現(xiàn)掃描儀連續(xù)掃描,只需一行代碼,就可實(shí)現(xiàn)一次掃描多張,且不需要更改掃描儀的任何設(shè)置,需要的朋友可以參考下2022-01-01
使用C#9中records作為強(qiáng)類型ID的實(shí)例教程
這篇文章主要給大家介紹了關(guān)于使用C#9中records作為強(qiáng)類型ID的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

