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#用websocket實(shí)現(xiàn)簡(jiǎn)易聊天功能(服務(wù)端)
這篇文章主要為大家詳細(xì)介紹了C#用websocket實(shí)現(xiàn)簡(jiǎn)易聊天功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02C#利用RabbitMQ實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)消息傳輸
RabbitMQ做為消息代理,負(fù)責(zé)接收和轉(zhuǎn)發(fā)消息,可以將RabbitMQ比喻為一個(gè)郵筒、一個(gè)郵局和一個(gè)郵遞員。本文主要以一個(gè)簡(jiǎn)單的小例子,簡(jiǎn)述RabbitMQ實(shí)現(xiàn)消息傳輸?shù)南嚓P(guān)內(nèi)容,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正。2021-05-05基于C#實(shí)現(xiàn)Windows服務(wù)的方法詳解
在實(shí)際應(yīng)用過程中,有時(shí)候我們希望開發(fā)的程序,不需要界面,直接開機(jī)就可以長(zhǎng)時(shí)間運(yùn)行,這時(shí)候,我們可以考慮做成一個(gè)Windows服務(wù)。這篇文章跟大家介紹一下,如何基于C#實(shí)現(xiàn)Windows服務(wù)的創(chuàng)建、安裝、啟動(dòng)、停止和卸載,需要的可以參考一下2022-09-09C# WebApi Get請(qǐng)求方式傳遞實(shí)體參數(shù)的方法示例
這篇文章主要給大家介紹了關(guān)于C# WebApi Get請(qǐng)求方式傳遞實(shí)體參數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04C#調(diào)用C++動(dòng)態(tài)庫接口函數(shù)和回調(diào)函數(shù)方法
這篇文章主要介紹了C#調(diào)用C++動(dòng)態(tài)庫接口函數(shù)和回調(diào)函數(shù)方法,通過C++端編寫接口展開內(nèi)容,文章介紹詳細(xì)具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-03-03C#操作SQLite數(shù)據(jù)庫方法小結(jié)(創(chuàng)建,連接,插入,查詢,刪除等)
這篇文章主要介紹了C#操作SQLite數(shù)據(jù)庫方法,包括針對(duì)SQLite數(shù)據(jù)庫的創(chuàng)建,連接,插入,查詢,刪除等操作,并提供了一個(gè)SQLite的封裝類,需要的朋友可以參考下2016-07-07C#實(shí)現(xiàn)設(shè)置或屏蔽熱鍵的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)設(shè)置或屏蔽熱鍵,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12