写了一个选择题Demo,电脑包和编辑器内无问题,但是打包安卓手机之后题目无法正常使用,想到的是安卓环境中正确地读取文件的问题
改进方案:
1.由于 XmlDocument.Load
方法在 Android 上的路径问题(由于文件位于 APK 内部,无法像在文件系统中那样直接访问),需要先使用 UnityWebRequest
来异步加载文件内容,然后再解析 XML。
2.异步处理:修改你的代码,以支持异步文件加载和处理,这对于避免在加载大文件时造成的界面冻结也很有帮助。
代码对比:
初版:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Xml;
using System.Text;
public class xmlres : MonoBehaviour
{
[SerializeField]
private List<Toggle> toggleList;//答案ABC
[SerializeField]
private Text TM_Text;//题目
[SerializeField]
private List<Text> DA_TextList;//选项
private int topNumber = 0;
private string selectAnswer = " ";
private bool isSelect = false;//是否选中
/* 确定五道题 */
List<xmlData> xmls = new List<xmlData>();
List<xmlData> useArray = new List<xmlData>();
HashSet<xmlData> xmlDatas = new HashSet<xmlData>();
//public GameObject selectPanel;
//public GameObject wrongPanel;
public static xmlres instance;
private void Awake()
{
instance = this;
}
void Start()
{
ReadQuestion();
toggleList[0].onValueChanged.AddListener(OnValChanged0);
toggleList[1].onValueChanged.AddListener(OnValChanged1);
toggleList[2].onValueChanged.AddListener(OnValChanged2);
}
void OnValChanged0(bool check)
{
//Debug.Log(check);
if (check)
{
selectAnswer = "A";
isSelect = true;
}
}
void OnValChanged1(bool check)
{
//Debug.Log(check);
if (check)
{
selectAnswer = "B";
isSelect = true;
}
}
void OnValChanged2(bool check)
{
//Debug.Log(check);
if (check)
{
selectAnswer = "C";
isSelect = true;
}
}
public void ReadQuestion()
{
string url = Application.streamingAssetsPath + "/myxml.xml";
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load(url);
//获取所有题目
int XmlCount = XmlDoc.GetElementsByTagName("Timu").Count;
Debug.Log(XmlCount);
//解析每一个题目
for (int i = 0; i < XmlCount; i++)
{
xmlData temp = new xmlData();
XmlNodeList ls = XmlDoc.GetElementsByTagName("Timu")[i].ChildNodes;
temp.key = ls[0].InnerText;
temp.title = ls[1].InnerText;
temp.q1 = ls[2].InnerText;
temp.q2 = ls[3].InnerText;
temp.q3 = ls[4].InnerText;
temp.answer = ls[5].InnerText;
//存储到题库
xmls.Add(temp);
}
GetFiveQuestions();
//foreach (var item in useArray)
//{
// Debug.Log(item);
//}
}
//判断问题是否正确
public bool PanDuan(int topNumber, string answer)
{
foreach (var item in useArray)
{
if (useArray[topNumber].answer == answer)
{
//Debug.Log("zhengque");
return true;
}
else
{
//Debug.Log("cuowu");
return false;
}
}
return false;
}
/// <summary>
/// 得到五道题
/// </summary>
public void GetFiveQuestions()
{
for (int i = 0; i < 5; i++)
{
A1: int index = Random.Range(0, 15);
if (xmlDatas.Add(xmls[index]))
{
useArray.Add(xmls[index]);
}
else
{
goto A1;
}
}
ResetTimu(topNumber);
}
/// <summary>
/// 初始化题目
/// </summary>
/// <param name="index"></param>
public void ResetTimu(int index)
{
for (int i = 0; i < toggleList.Count; i++)
{
toggleList[i].isOn = false;
}
for (int i = 0; i < DA_TextList.Count; i++)
{
TM_Text.text = useArray[index].title;
switch (i)
{
case 0:
DA_TextList[i].text = useArray[index].q1;
break;
case 1:
DA_TextList[i].text = useArray[index].q2;
break;
case 2:
DA_TextList[i].text = useArray[index].q3;
break;
}
}
}
/// <summary>
/// 确定之后进入下一题
/// </summary>
public void BtnClick()
{
//print(isSelect);
if (topNumber == 4)
{
Debug.Log("答完了");
}
if (isSelect == true)
{
if (topNumber < 5)
{
if (PanDuan(topNumber, selectAnswer))
{
topNumber++;
if (topNumber<5)
{
ResetTimu(topNumber);
}
isSelect = false;
print("选择正确");
}
else
{
topNumber++;
if (topNumber < 5)
{
ResetTimu(topNumber);
}
isSelect = false;
print("选择错误");
}
}
else
{
return;
}
}
else
{
return;
}
}
}
改进版:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Xml;
public class xmlres : MonoBehaviour
{
[SerializeField]
private List<Toggle> toggleList; // 答案ABC
[SerializeField]
private Text TM_Text; // 题目
[SerializeField]
private List<Text> DA_TextList; // 选项
private int topNumber = 0;
private string selectAnswer = " ";
private bool isSelect = false; // 是否选中
List<xmlData> xmls = new List<xmlData>();
List<xmlData> useArray = new List<xmlData>();
HashSet<xmlData> xmlDatas = new HashSet<xmlData>();
public static xmlres instance;
private void Awake()
{
instance = this;
}
void Start()
{
StartCoroutine(ReadQuestion());
toggleList[0].onValueChanged.AddListener(OnValChanged0);
toggleList[1].onValueChanged.AddListener(OnValChanged1);
toggleList[2].onValueChanged.AddListener(OnValChanged2);
}
IEnumerator ReadQuestion()
{
string url = Path.Combine(Application.streamingAssetsPath, "myxml.xml");
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(www.downloadHandler.text);
int XmlCount = xmlDoc.GetElementsByTagName("Timu").Count;
Debug.Log(XmlCount);
for (int i = 0; i < XmlCount; i++)
{
xmlData temp = new xmlData();
XmlNodeList ls = xmlDoc.GetElementsByTagName("Timu")[i].ChildNodes;
temp.key = ls[0].InnerText;
temp.title = ls[1].InnerText;
temp.q1 = ls[2].InnerText;
temp.q2 = ls[3].InnerText;
temp.q3 = ls[4].InnerText;
temp.answer = ls[5].InnerText;
xmls.Add(temp);
}
GetFiveQuestions();
}
}
void OnValChanged0(bool check)
{
if (check)
{
selectAnswer = "A";
isSelect = true;
}
}
void OnValChanged1(bool check)
{
if (check)
{
selectAnswer = "B";
isSelect = true;
}
}
void OnValChanged2(bool check)
{
if (check)
{
selectAnswer = "C";
isSelect = true;
}
}
public bool PanDuan(int topNumber, string answer)
{
if (useArray[topNumber].answer == answer)
{
return true;
}
else
{
return false;
}
}
public void GetFiveQuestions()
{
xmlDatas.Clear();
useArray.Clear();
while (useArray.Count < 5)
{
int index = Random.Range(0, xmls.Count);
if (xmlDatas.Add(xmls[index]))
{
useArray.Add(xmls[index]);
}
}
ResetTimu(topNumber);
}
public void ResetTimu(int index)
{
TM_Text.text = useArray[index].title;
DA_TextList[0].text = useArray[index].q1;
DA_TextList[1].text = useArray[index].q2;
DA_TextList[2].text = useArray[index].q3;
foreach (var toggle in toggleList)
{
toggle.isOn = false;
}
}
public void BtnClick()
{
if (isSelect)
{
bool correct = PanDuan(topNumber, selectAnswer);
if (correct)
{
Debug.Log("选择正确");
}
else
{
Debug.Log("选择错误");
}
topNumber++;
if (topNumber < 5)
{
ResetTimu(topNumber);
}
else
{
Debug.Log("答完了");
}
isSelect = false;
}
}
}
public class xmlData
{
public string key;
public string title;
public string q1;
public string q2;
public string q3;
public string answer;
}