选择题UI
QuestionInfoSetting.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class QuestionInfoSetting : MonoBehaviour
{
[Header("选项")]
public GameObject OptionItem;
[Header("选项父级")]
public GameObject optionsFather;
[Header("选择题类型")]
public GameObject typeSingle, typeMultip;
[Header("答案提示")]
public GameObject answerTip;
//public GameObject rightImg, errorImg;
public TextMeshProUGUI titleTxt, judgeTxt, answerTxt;
[Header("解析")]
public TextMeshProUGUI parseRight, parseError;
[Header("确定按钮")]
public GameObject confimBtn;
[Header("本地题库")]
public QuestionConfig questionConfig;
[Header("回答错误/正确语音")]
public AudioClip[] clipArr;
public Action<bool> actAnswerFinished;
private QuesItem quesItem;
private int singleAnswer = -1;
private List<int> mulptiAnswer = new List<int>();
private bool isRight = true;
private List<Transform> itemList = new List<Transform>();
private void OnDestroy()
{
itemList.Clear();
mulptiAnswer.Clear();
if (actAnswerFinished != null)
{
actAnswerFinished = null;
}
}
/// <summary>
/// 解锁问题
/// </summary>
/// <param name="id">问题id。取值范围:大于0的正整数</param>
/// <returns></returns>
public bool UnlockQuestion(int id)
{
if (questionConfig == null) return false;
if(questionConfig.quesItems.Length < id || id<=0) return false;
//删除之前的克隆体
var transformArr = optionsFather.GetComponentsInChildren<Transform>();
foreach (var child in transformArr)
{
if (child.gameObject.name.Contains("Clone"))
{
child.gameObject.SetActive(false);
child.gameObject.GetComponent<Button>().onClick.RemoveAllListeners();
GameObject.Destroy(child.gameObject);
}
}
confimBtn.GetComponent<Button>().onClick.RemoveListener(OnBtnConfimClicked);
confimBtn.GetComponent<Button>().onClick.AddListener(OnBtnConfimClicked);
// rightImg.SetActive(false);
// errorImg.SetActive(false);
this.parseRight.gameObject.transform.parent.gameObject.SetActive(false);
this.parseError.gameObject.transform.parent.gameObject.SetActive(false);
judgeTxt.gameObject.SetActive(false);
answerTxt.gameObject.SetActive(false);
itemList.Clear();
//answerTip.SetActive(false);
quesItem = questionConfig.quesItems[id - 1];
if("单选题" != quesItem.type && "多选题" == quesItem.type)
{
quesItem.type = quesItem.standardAnswers.Count > 1 ? "多选题" : "单选题";
}
typeSingle.SetActive("单选题" == quesItem.type);
typeMultip.SetActive("多选题" == quesItem.type);
titleTxt.text = quesItem.title;
//创建选项
CreateOptions();
return true;
}
/// <summary>
/// 选项被点击
/// </summary>
/// <param name="obj"></param>
public void OnOptionClicked(GameObject obj)
{
int index = -1;
if (itemList.Contains(obj.transform))
{
index = itemList.IndexOf(obj.transform);
}
if ("单选题" == quesItem.type)
{
if(singleAnswer != index
&& singleAnswer != -1
&& singleAnswer <= itemList.Count)
{
itemList[singleAnswer].gameObject.transform.GetChild(0).gameObject.SetActive(false);
}
singleAnswer = index;
obj.transform.GetChild(0).gameObject.SetActive(true);
}
else if ("多选题" == quesItem.type)
{
if (mulptiAnswer.Contains(index))
{
mulptiAnswer.Remove(index);
obj.transform.GetChild(0).gameObject.SetActive(false);
}
else
{
mulptiAnswer.Add(index);
obj.transform.GetChild(0).gameObject.SetActive(true);
}
}
}
#region --------私有方法--------
/// <summary>
/// 创建选项
/// </summary>
private void CreateOptions()
{
if (OptionItem == null || optionsFather == null) return;
mulptiAnswer.Clear();
OptionItem.SetActive(true);
for (int i=0; i< quesItem.options.Length; i++)
{
var item = GameObject.Instantiate(OptionItem, optionsFather.transform);
item.GetComponentInChildren<TextMeshProUGUI>().text = quesItem.options[i].content.Substring(2);
//TODO:
}
OptionItem.SetActive(false);
//缓存选项transform信息
var transformArr = optionsFather.GetComponentsInChildren<Transform>();
foreach (var child in transformArr)
{
if (child.gameObject.name.Contains("Clone"))
{
itemList.Add(child);
}
}
gameObject.SetActive(true);
}
/// <summary>
/// 响应确定按钮点击事件
/// </summary>
private void OnBtnConfimClicked()
{
string strBtnName = confimBtn.GetComponentInChildren<TextMeshProUGUI>().text;
if ("确 定" == strBtnName)
{
if(singleAnswer == -1 && mulptiAnswer.Count == 0)
{//还未选择任何选项
return;
}
//不允许再点击选项了
var transformArr = optionsFather.GetComponentsInChildren<Transform>();
foreach (var child in transformArr)
{
if (child.gameObject.name.Contains("Clone"))
{
child.gameObject.GetComponent<Button>().onClick.RemoveAllListeners();
child.gameObject.GetComponent<Button>().interactable = false;
}
}
if ("单选题" == quesItem.type)
{
isRight = singleAnswer == quesItem.standardAnswers[0];
}
else if("多选题" == quesItem.type)
{
isRight = true;
if(mulptiAnswer.Count != quesItem.standardAnswers.Count)
{
isRight = false;
}
else
{
foreach (var i in mulptiAnswer)
{
if (quesItem.standardAnswers.Contains(i))
{
continue;
}
else
{
isRight = false;
break;
}
}
}
}
//answerTip.SetActive(true);
// rightImg.SetActive(isRight);
// errorImg.SetActive(!isRight);
judgeTxt.text = isRight ? "选择正确!" : "选择错误!";
judgeTxt.color = isRight? Color.green : Color.red;
judgeTxt.gameObject.SetActive(true);
answerTip.GetComponent<AudioSource>().clip = isRight ? clipArr[1] : clipArr[0];
answerTip.GetComponent<AudioSource>().Play();
string answerTemp = "";
foreach (var answer in quesItem.standardAnswers)
{
if (!isRight && itemList.Count > answer)
{//选择错误后,将正确选项背景变绿
itemList[answer].gameObject.GetComponent<ReferenceCollector>().Get<GameObject>("ImageRight").SetActive(true);
}
answerTemp += NumberToChar(answer);
}
answerTxt.text = "正确答案:" + answerTemp;
answerTxt.color = isRight? Color.green : Color.red;
answerTxt.gameObject.SetActive(true);
if ("" != this.quesItem.parse)
{//如果解析不为空,显示解析
this.parseRight.text = this.quesItem.parse;
this.parseRight.gameObject.transform.parent.gameObject.SetActive(isRight);
this.parseError.text = this.quesItem.parse;
this.parseError.gameObject.transform.parent.gameObject.SetActive(!isRight);
}
confimBtn.GetComponentInChildren<TextMeshProUGUI>().text = "关 闭";
WaitAMoment(2, confimBtn.GetComponent<Button>());
}
else
{
actAnswerFinished?.Invoke(isRight);
gameObject.SetActive(false);
isRight = true;
singleAnswer = -1;
mulptiAnswer.Clear();
confimBtn.GetComponentInChildren<TextMeshProUGUI>().text = "确 定";
//删除之前的克隆体
var transformArr = optionsFather.GetComponentsInChildren<Transform>();
foreach (var child in transformArr)
{
if (child.gameObject.name.Contains("Clone"))
{
child.gameObject.SetActive(false);
child.gameObject.GetComponent<Button>().onClick.RemoveAllListeners();
GameObject.Destroy(child.gameObject);
}
}
}
}
private async void WaitAMoment(float time, Button bch)
{
bch.interactable = false;
await Task.Delay((int)time * 1000);
bch.interactable = true;
}
/// <summary>
/// 根据Ascii码转换,将0~25转换为A~Z
/// </summary>
/// <param name="_num"></param>
/// <returns></returns>
private static string NumberToChar(int _num)
{
string strTemp = "";
if (_num >= 0 && _num < 26)
{
int num = _num + 65;
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
byte[] btNumber = new byte[] { (byte)num };
strTemp = asciiEncoding.GetString(btNumber);
}
return strTemp;
}
#endregion --------------------
}
using UnityEngine;
public class ChangeOptionBG : MonoBehaviour
{
public GameObject Selected, Dedault;
public void Init(bool _isSelected)
{
Selected.SetActive(_isSelected);
//Dedault?.SetActive(!_isSelected);
}
}
本地选择题库配置
using System;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName ="CreateQuesCfg")]
public class QuestionConfig : ScriptableObject
{
public QuesItem[] quesItems;
}
[Serializable]
public class QuesItem
{
public int id;
public string title;
public string type;
public string parse;
public List<int> standardAnswers;
public List<int> myAnswers;
public OptionItem[] options;
}
[Serializable]
public class OptionItem
{
public string content;
public bool isRight;
}