Unity答题系统2.0版本(修改答题面板形式(滚动视图显示),增加提交后得分结果显示)
Posted 多放点儿香菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity答题系统2.0版本(修改答题面板形式(滚动视图显示),增加提交后得分结果显示)相关的知识,希望对你有一定的参考价值。
搭建答题面板
1.添加一个画布(Canvas),在画布下新建一个空物体(Panel_Question),在空物体下添加一张图片(Image),作为答题背景图。然后在背景图下添加一个滚动视图(Scroll View),调整好宽高。在滚动视图的Content物体下新建空物体(Question),作为一道题目的父物体,content物体上添加两个组件【Content Size Fitter】和【Vertical Layout Group】,并设置相关属性和适当的参数,使其子物体可以自适应垂直布局。设置可参考下图:
-
题目(Question)物体下,添加Text文本(topic)作为问题文本;新建空物体(Item)作为选项的父物体,item下添加一个Toggle组件作为选项(命名为option),默认不勾选,添加组件【Layout Element】可以自动布局下设置其宽高;item物体上添加组件【Vertical Layout Group】和【Toggle Group】,分别用来控制选项的垂直布局和选项Toggle组的选中转台,其属性Allow Switch Off默认不勾选,表示在改组下,仅有一个toggle可以被选中,如果勾选,改组下所有toggle都可以不被选中。item面板如下:
再添加一张image(命名为line),作为题目与题目之间的分割线。其面板如下:
最后为题目Question物体添加组件【Vertical Layout Group】,设置如下:
还要将题目Question物体和选项option物体,拖到Resources文件加下作为预制体,用来实例化生成。
最终答题面板效果如下:
-
添加确认框和得分面板
这两个很容易搭建,就是image、text、button拼接组合,不再详细描述,效果如下:
4.新建Data文件夹保存题目的xml文档
xml文档内容如下:
可根据需求修改。
脚本实现答题功能
1.NewQuestion.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using UnityEngine.UI;
/// <summary>
/// 答题界面
/// </summary>
public class NewQuestion : MonoBehaviour
/// <summary>
/// 题库xml路径
/// </summary>
private string problemXmlPath = "/Data/Problem.xml";
/// <summary>
/// 题目的父物体
/// </summary>
private Transform questionParent;
/// <summary>
/// 确认框
/// </summary>
private Transform hintBG;
/// <summary>
/// 确认提交面板
/// </summary>
private GameObject affirmPanel;
/// <summary>
/// 得分结果面板
/// </summary>
private GameObject resultPanel;
/// <summary>
/// 得分内容
/// </summary>
private Text resultText;
/// <summary>
/// 用来缓存每一道题目的答题情况数据
/// </summary>
private List<QuestionItem> questionItems;
private void Start()
resultPanel = transform.Find("hintBG/resultPanel").gameObject;
affirmPanel = transform.Find("hintBG/affirmPanel").gameObject;
resultText = resultPanel.GetComponentInChildren<Text>();
SetActive(false, resultPanel, affirmPanel);
resultPanel.gameObject.SetActive(false);
questionParent = transform.Find("answerBG/Scroll View/Viewport/Content");
hintBG = transform.Find("hintBG");
hintBG.localScale = Vector3.zero;
transform.Find("answerBG/SubmitBtn").GetComponent<Button>().onClick.AddListener(() =>
hintBG.localScale = Vector3.one;
SetActive(true, affirmPanel);
);
transform.Find("hintBG/affirmPanel/cancelBtn").GetComponent<Button>().onClick.AddListener(() =>
hintBG.localScale = Vector3.zero;
);
transform.Find("hintBG/affirmPanel/submitBtn").GetComponent<Button>().onClick.AddListener(SubmitClick);
Init();
questionItems = new List<QuestionItem>();
/// <summary>
/// 设置物体显隐
/// </summary>
/// <param name="value"></param>
/// <param name="obj"></param>
private void SetActive(bool value, params GameObject[] obj )
foreach (var item in obj)
item.SetActive(value);
/// <summary>
/// 提交事件
/// </summary>
private void SubmitClick()
int score = 0;
int rightCount = 0;
int wrongCount = 0;
int notAnswerCount = 0;
score = problem.problemData[0].score;
for (int i = 0; i < problem.problemData.Count; i++)
//是否已选择
if (questionItems[i].IsSelect)
//是否选择正确
if (questionItems[i].isRight)
rightCount++;
else
wrongCount++;
else
notAnswerCount++;
resultText.text = string.Format("一共有0道题,每题1分,你答对了2道题,答错了3道题,4道题未作答,总得分5分。", problem.problemData.Count, score.ToString(), rightCount.ToString(), wrongCount.ToString(), notAnswerCount.ToString(), (rightCount*score).ToString());
SetActive(false, affirmPanel);
SetActive(true, resultPanel);
/// <summary>
/// 初始化协程解析xml数据
/// </summary>
public void Init()
StartCoroutine(LoadingQuestion(problemXmlPath));
/// <summary>
/// 题库
/// </summary>
private Problem problem;
/// <summary>
/// 解析题目xml文件
/// </summary>
/// <param name="path">xml路径</param>
/// <returns></returns>
IEnumerator LoadingQuestion(string path)
string filePath= "file://"+Application.dataPath + path;
yield return null;
using (WWW www=new WWW(filePath))
yield return www;
XmlDocument doc = new XmlDocument();
doc.LoadXml(www.text);
problem=new Problem(doc.FirstChild);
//遍历题库生成所有题目
for (int i = 0; i < problem.problemData.Count; i++)
CreateQuestionItem(problem.problemData[i]);
/// <summary>
/// 创建一道题目
/// </summary>
/// <param name="problemData">一道题的数据</param>
private void CreateQuestionItem(ProblemData problemData)
//生成问题
QuestionItem questionItem = GameObject.Instantiate(Resources.Load<QuestionItem>("Prefab/Question"));
questionItem.transform.SetParent(questionParent);
questionItem.transform.localScale = Vector3.one;
questionItem.topicText.text = problemData.topicStr;
//生成问题对应的选项
for (int i = 0; i < problemData.optionData.Count; i++)
Toggle toggle = GameObject.Instantiate(Resources.Load<Toggle>("Prefab/option") as Toggle);
toggle.transform.SetParent(questionItem.item);
toggle.transform.localScale = Vector3.one;
toggle.group = questionItem.itemGroup;
questionItem.ItemInit(toggle, problemData.optionData[i]);
questionItems.Add(questionItem);
/// <summary>
/// 题库内容类
/// </summary>
public class Problem
public List<ProblemData> problemData;
/// <summary>
/// 遍历根节点下的子节点
/// </summary>
/// <param name="node">传入的是根节点Root</param>
public Problem(XmlNode node)
problemData = new List<ProblemData>();
for (int i = 0; i < node.ChildNodes.Count; i++)
problemData.Add(new ProblemData(node.ChildNodes[i]));
/// <summary>
/// 每一道题目
/// </summary>
public class ProblemData
/// <summary>
/// 题目分数
/// </summary>
public int score;
/// <summary>
/// 题目内容
/// </summary>
public string topicStr;
/// <summary>
/// 每道题对应的选项
/// </summary>
public List<OptionData> optionData;
/// <summary>
/// 解析question节点数据
/// 有多少个question节点就有多少道题目
/// </summary>
/// <param name="node">传入的是Question节点</param>
public ProblemData(XmlNode node)
score =int.Parse(node.Attributes["score"].InnerText);
topicStr = node["Topic"].InnerText;
optionData = new List<OptionData>();
XmlNodeList nodelist = node["Answer"].ChildNodes;
for (int i = 0; i < nodelist.Count; i++)
optionData.Add(new OptionData(nodelist[i]));
/// <summary>
/// 题目对应的选项
/// </summary>
public class OptionData
/// <summary>
/// 选项内容
/// </summary>
public string optionStr;
/// <summary>
/// 选项对应的分值
/// </summary>
public int score;
/// <summary>
/// 解析选项节点
/// </summary>
/// <param name="node">传入的是Item节点</param>
public OptionData(XmlNode node)
optionStr = node.Attributes["Name"].InnerText;
score = int.Parse(node.InnerText);
挂载到Panel_Question物体上:
2.QuestionItem.cs
这个脚本表示每一道题的实例对象,用来缓存题目的数据
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 每一道题
/// </summary>
public class QuestionItem : MonoBehaviour
/// <summary>
/// 题目内容
/// </summary>
public Text topicText;
/// <summary>
/// 选项的父物体
/// </summary>
public Transform item;
/// <summary>
/// 一道题的Toggle组
/// </summary>
public ToggleGroup itemGroup;
/// <summary>
/// 当前题目是否选择正确
/// </summary>
public bool isRight;
/// <summary>
/// 当前题目是否选择答案
/// </summary>
public bool IsSelect = false;
private Color selectColor;
/// <summary>
/// 初始化选项Toggel的内容
/// </summary>
/// <param name="toggle"></param>
/// <param name="optionData"></param>
public void ItemInit(Toggle toggle,OptionData optionData)
toggle.GetComponentInChildren<Text>().text = optionData.optionStr;
//为每一个选择添加选中事件
toggle.onValueChanged.AddListener((isSelect)=>
IsSelect = isSelect;
//修改选中的选项的颜色
ColorUtility.TryParsehtmlString("#F1BC52FF", out selectColor);
toggle.GetComponentInChildren<Text>().color = selectColor;
//当前题目选中的选项变颜色,其他选项恢复默认颜色
for (int i = 0; i < item.childCount; i++)
if (!item.GetChild(i).GetComponent<Toggle>().isOn)
item.GetChild(i).GetComponentInChildren<Text>().color = Color.black;
else
//选项对应分值大于0表示该选项是正确答案,否则是错误答案
if (optionData.score>0)
isRight = true;
else
isRight = false;
);
挂载到Question物体上:
实现效果
直接运行即可
初始效果:
答题效果:
得分显示效果:
如果不了解如何解析xml节点信息的请参考答题系统1.0版本
文末有对解析xml节点的介绍。
2.0版本没有写多选题的相关逻辑,如要需要也可参考1.0版本,添加多选题逻辑和xml配置信息。
以上是关于Unity答题系统2.0版本(修改答题面板形式(滚动视图显示),增加提交后得分结果显示)的主要内容,如果未能解决你的问题,请参考以下文章