当前位置:   article > 正文

Unity答题系统案例

unity答题系统

前言

Unity答题系统,可适配单选或多选

偶然看到一种使用二进制表示选项的方法,让我茅塞顿开,没想到还能有这样的思路,所以拿出来分享一下

运行示例

 方法思路

我这里答题系统做了一个简单的案例,思路主要是以下几点

  1. 通过读取StreamingAssets文件内的xml文件来获取题库,题库内存储的数据我会在下面介绍,后期打包后也可以修改题库
  2. 然后就是自定义类,存储获取到的题库
  3. 最后通过读取题库中的存储的十进制数,将十进制数转化为二进制,然后对照ASCII码表来匹配正确答案

 获取题库方法

  1. void GetData()
  2. {
  3. if (File.Exists(path))
  4. {
  5. XmlDocument xmldoc = new XmlDocument();
  6. xmldoc.Load(path);
  7. XmlNodeList nodeList = xmldoc.SelectSingleNode("Root").ChildNodes;
  8. topic_Count = nodeList.Count;
  9. foreach (XmlElement xel in nodeList) //36
  10. {
  11. int order = int.Parse(xel.GetAttribute("id"));
  12. Data data = new Data();
  13. foreach (XmlElement xe2 in xel.ChildNodes)
  14. {
  15. int j = 0;
  16. foreach (XmlElement xe3 in xe2.ChildNodes)
  17. {
  18. switch (j)
  19. {
  20. case 0:
  21. {
  22. data.question.key = int.Parse(xe3.GetAttribute("key"));
  23. data.question.title = xe3.InnerText;
  24. }
  25. break;
  26. default:
  27. data.question.answer.Add(xe3.InnerText);
  28. data.question.isAnswer = new bool[data.question.answer.Count];
  29. break;
  30. }
  31. j++;
  32. }
  33. }
  34. QuestionBanks.Add(order, data);
  35. }
  36. }
  37. }

xml题库文件配置如下

自定义类

  1. public class Data
  2. {
  3. public int order;
  4. public Question question = new Question();
  5. }
  6. public class Question
  7. {
  8. public string title;
  9. public List<string> answer = new List<string>();
  10. public bool[] isAnswer;
  11. public int key;
  12. }
  13. public enum BtnState
  14. {
  15. normal,
  16. check,
  17. complete
  18. }

答题卡部分

  1. void ShowAnswerCard()
  2. {
  3. if (topic_Count > 0)
  4. {
  5. Debug.Log(topic_Count);
  6. for (int i = 1; i <= topic_Count; i++)
  7. {
  8. GameObject obj = Instantiate(card);
  9. obj.name = i.ToString();
  10. obj.transform.SetParent(cardContent);
  11. obj.GetComponentInChildren<Text>().text = i.ToString();
  12. //存入答题卡列表
  13. card_btn.Add(obj.GetComponent<Button>());
  14. }
  15. }
  16. }

转化题库key值为选项

  1. public static string NumToABC(int num)
  2. {
  3. string str = Convert.ToString(num, 2);
  4. string strResult = null;
  5. for (int i = str.Length - 1, j = 0; i >= 0; i--)
  6. {
  7. if (str.Length >= i)
  8. {
  9. string c = str.Substring(str.Length - 1, 1);
  10. //转化Ascii码
  11. if (c != "0")
  12. {
  13. char a = (char)(i + 65);
  14. if (j == 0)
  15. {
  16. strResult += a;
  17. }
  18. else
  19. {
  20. strResult += "," + a;
  21. }
  22. j++;
  23. }
  24. }
  25. }
  26. if (strResult == null)
  27. {
  28. return "(未选择)";
  29. }
  30. else
  31. {
  32. return strResult;//返回转化后的选项
  33. }
  34. }

更新题库内容

  1. private void InitateTopic(int order)
  2. {
  3. //进入之后先判断是否有选项-有选项匹配选项内容,无选项默认
  4. // up down 切换 直接选择切换
  5. if (order == 0 || order > QuestionBanks.Count)
  6. {
  7. Debug.Log("序列号有误" + order + " " + QuestionBanks.Count);
  8. return;
  9. }
  10. if (GetComponent<ToggleGroup>())
  11. {
  12. Destroy(GetComponent<ToggleGroup>());
  13. }
  14. data = QuestionBanks[order];
  15. int letterCount = Regex.Matches(NumToABC(data.question.key), "[a-zA-Z]").Count;
  16. bool tog_IsOn = false;
  17. for (int i = 0; i < answer_Tog.Length; i++)
  18. {
  19. answer_Tog[i].group = null;
  20. answer_Tog[i].isOn = data.question.isAnswer[i];
  21. answer_Tog[i].interactable = false;
  22. answer_Tog[i].GetComponentInChildren<Text>().text = data.question.answer[i];
  23. if (answer_Tog[i].isOn)
  24. {
  25. Debug.Log("有选项");
  26. tog_IsOn = true;
  27. }
  28. }
  29. if (tog_IsOn)
  30. {
  31. Debug.Log("有选项");
  32. ensure_Btn.interactable = false;
  33. if (selectedButton.image.color != selectedButton.colors.pressedColor)
  34. {
  35. selectedButton.image.color = selectedButton.colors.normalColor;
  36. }
  37. card_btn[currentOrder - 1].image.color = card_btn[currentOrder - 1].colors.pressedColor;
  38. selectedButton = card_btn[currentOrder - 1];
  39. if (GetComponent<ToggleGroup>())
  40. {
  41. Destroy(GetComponent<ToggleGroup>());
  42. }
  43. if (letterCount <= 1)
  44. {
  45. for (int i = 0; i < answer_Tog.Length; i++)
  46. {
  47. answer_Tog[i].isOn = data.question.isAnswer[i];
  48. }
  49. title_Txt.text = "<color=#FFFFFF00>XX</color>" +order+"."+ data.question.title+"(单选题)";
  50. }
  51. else
  52. {
  53. Debug.Log("多选");
  54. for (int i = 0; i < answer_Tog.Length; i++)
  55. {
  56. answer_Tog[i].isOn = data.question.isAnswer[i];
  57. }
  58. title_Txt.text = "<color=#FFFFFF00>XX</color>" + order + "." + data.question.title+"(多选题)";
  59. }
  60. }
  61. else
  62. {
  63. // Debug.Log("无选项"+selectedButton.name+" "+currentOrder);
  64. ensure_Btn.interactable = true;
  65. if (selectedButton.image.color!= selectedButton.colors.pressedColor)
  66. {
  67. selectedButton.image.color =selectedButton.colors.normalColor;
  68. }
  69. card_btn[currentOrder - 1].image.color = card_btn[currentOrder - 1].colors.highlightedColor;
  70. selectedButton = card_btn[currentOrder - 1];
  71. if (letterCount <= 1)
  72. {
  73. if (GetComponent<ToggleGroup>() == null)
  74. {
  75. gameObject.AddComponent<ToggleGroup>();
  76. }
  77. for (int i = 0; i < answer_Tog.Length; i++)
  78. {
  79. answer_Tog[i].group=GetComponent<ToggleGroup>();
  80. answer_Tog[i].isOn = false;
  81. answer_Tog[i].interactable = true;
  82. }
  83. GetComponent<ToggleGroup>().allowSwitchOff = true;
  84. title_Txt.text = "<color=#FFFFFF00>XX</color>" + order + "." + data.question.title+ "(单选题)";
  85. }
  86. else
  87. {
  88. if (GetComponent<ToggleGroup>())
  89. {
  90. Destroy(GetComponent<ToggleGroup>());
  91. }
  92. for (int i = 0; i < answer_Tog.Length; i++)
  93. {
  94. answer_Tog[i].interactable = true;
  95. answer_Tog[i].isOn = false;
  96. }
  97. title_Txt.text = "<color=#FFFFFF00>XX</color>" + order + "." + data.question.title + "(多选题)";
  98. }
  99. //存入四个选项状态
  100. ensure_Btn.onClick.AddListener(() =>
  101. {
  102. ensure_Btn.interactable = false;
  103. if (GetComponent<ToggleGroup>())
  104. {
  105. Destroy(GetComponent<ToggleGroup>());
  106. }
  107. AnswerClose(data);
  108. string key = string.Empty;
  109. key = string.Format("{0:D4}", int.Parse(Convert.ToString(data.question.key, 2)));
  110. for (int i = 0; i < data.question.answer.Count; i++)
  111. {
  112. if (key.Substring(3 - i, 1) == "1" && !answer_Tog[i].isOn)
  113. {
  114. Debug.Log("选择错误");
  115. return;
  116. }
  117. else if (key.Substring(3 - i, 1) == "0" && answer_Tog[i].isOn)
  118. {
  119. Debug.Log("选择错误");
  120. return;
  121. }
  122. }
  123. Debug.Log("选择正确");
  124. });
  125. }
  126. }

存储选项方法

  1. void AnswerClose(Data data)
  2. {
  3. for (int i = 0; i < answer_Tog.Length; i++)
  4. {
  5. answer_Tog[i].interactable = false;
  6. data.question.isAnswer[i] = answer_Tog[i].isOn;
  7. ensure_Btn.interactable = false;
  8. if (answer_Tog[i].isOn)
  9. {
  10. Debug.Log("有选择");
  11. card_btn[currentOrder - 1].image.color = card_btn[currentOrder - 1].colors.pressedColor;
  12. selectedButton = card_btn[currentOrder - 1];
  13. }
  14. }
  15. }
  1. private void Start()
  2. {
  3. order = int.Parse(GetComponentInChildren<Text>().text);
  4. btn.onClick.AddListener(() =>
  5. {
  6. QuestionBank.Instance.currentOrder = order;
  7. Debug.Log(QuestionBank.Instance.selectedButton.name);
  8. if (QuestionBank.Instance.selectedButton.GetComponent<CardBtn>().btnState!=BtnState.complete)
  9. {
  10. selectBtn = QuestionBank.Instance.selectedButton;
  11. QuestionBank.Instance.selectedButton.image.color = selectBtn.colors.normalColor;
  12. }
  13. QuestionBank.Instance.selectedButton = btn;
  14. QuestionBank.Instance.RestTopic();
  15. });
  16. }

 总结

一个简单的demo,还有很多可以扩展的空间,比如通过excel类型的题库读取,或者是多扩展出填空题之类的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/977695
推荐阅读
相关标签
  

闽ICP备14008679号