⭐Unity 安卓环境中正确地读取和处理 XML 文件

写了一个选择题Demo,++电脑包和编辑器++ 内无问题,但是打包++安卓手机++之后题目无法正常使用,想到的是安卓环境中正确地读取文件的问题

改进方案:

1.由于 XmlDocument.Load 方法在 Android 上的路径问题(由于文件位于 APK 内部,无法像在文件系统中那样直接访问),需要先使用 UnityWebRequest 来异步加载文件内容,然后再解析 XML。

2.异步处理:修改你的代码,以支持异步文件加载和处理,这对于避免在加载大文件时造成的界面冻结也很有帮助。

代码对比:

初版:

cs 复制代码
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;
        }


    }
   

    
}

改进版:

cs 复制代码
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;
}
相关推荐
Mr Lee_4 分钟前
android 配置鼠标右键快捷对apk进行反编译
android
顾北川_野39 分钟前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
&岁月不待人&1 小时前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
Sitarrrr1 小时前
【Unity】ScriptableObject的应用和3D物体跟随鼠标移动:鼠标放置物体在场景中
3d·unity
极梦网络无忧1 小时前
Unity中IK动画与布偶死亡动画切换的实现
unity·游戏引擎·lucene
Winston Wood3 小时前
Android Parcelable和Serializable的区别与联系
android·序列化
清风徐来辽3 小时前
Android 项目模型配置管理
android
帅得不敢出门3 小时前
Gradle命令编译Android Studio工程项目并签名
android·ide·android studio·gradlew
problc4 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
逐·風9 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#