首頁 > 軟體

Unity3D實戰之答題系統的實現

2022-03-10 19:24:07

一、前言

這是本專欄系列的第一篇,答題系統的開發。

這個答題系統,可以從文字檔案中提取題目和分數,然後繫結到UI上,在答題的過程中,自動判斷分數,自動判斷正確率。

目的是實現一個可快速匯入到專案中使用的小模組。

二、效果圖及工程下載

題目檔案  密碼:1234

源工程 

三、實現

1.介面搭建

首先,新建工程,然後擺UI,如下圖所示:

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.載入題目

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];//選項
        }
    }
}

題目正常載入:

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;
        }
    }

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、上一題下一題,選項選擇,跳轉,按鈕的功能實現

程式碼還是延期了一貫的簡潔風格,希望你可以在這篇文章學到東西。

以上就是Unity3D實戰之答題系統的實現的詳細內容,更多關於Unity3D答題系統的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com