一.应用场景
在项目开发过程中,我们可能会用到xml文件和txt文档以及其他类型的文件来保存项目中涉及到的角色信息、敌人信息、用户登录信息等等。
以下用一个小例子总结一下在Unity中读取xml和txt文件。
二.读取和保存xml
1.读取和保存xml,XMLManager类中的两个方法都能用来读取xml文件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
public class XMLManager
{
static XMLManager instance;
private XMLManager()
{
}
public static XMLManager Instance
{
get
{
if (instance == null)
instance = new XMLManager();
return instance;
}
}
public List<XMLPlayer> playerDataList = new List<XMLPlayer>(); //存放xml解析的数据
public XMLPlayerData playerData;
/// <summary>
/// 第一种加载方法
/// </summary>
/// <param name="path">xml文件路径</param>
public void LoadDataFromXML(string path)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(path);
XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//Player");
foreach(XmlNode node in xmlNodeList)
{
XMLPlayer player = new XMLPlayer();
player.id = int.Parse(node.SelectSingleNode("id").InnerText);
player.name = node.SelectSingleNode("name").InnerText;
player.attack = int.Parse(node.SelectSingleNode("attack").InnerText);
playerDataList.Add(player);
}
}
/// <summary>
/// 第二种加载方法
/// </summary>
/// <param name="path">xml文件路径</param>
public void LoadDataFromXml2(string path)
{
FileStream fileStream = new FileStream(path, FileMode.Open);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(XMLPlayerData));
playerData = xmlSerializer.Deserialize(fileStream) as XMLPlayerData; //将xml数据反序列化
fileStream.Close();
}
//保存XMl文件
public void SaveXml(string path)
{
FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(XMLPlayerData));
xmlSerializer.Serialize(fileStream, playerData); //将数据序列化成xml数据
fileStream.Close();
}
}
下面是代码中用到的XMLPlayer、XMLPlayer2、XMLPlayerData三个类。
public class XMLPlayer
{
public int id;
public string name;
public int attack;
public override string ToString()
{
return "id:" + id + " name:" + name + " attack:" + attack;
}
}
public class XMLPlayer2
{
[XmlAttribute(AttributeName = "id")]
public int id;
[XmlAttribute(AttributeName ="name")]
public string name;
[XmlAttribute(AttributeName = "attack")]
public int attack;
//重写ToString()方法
public override string ToString()
{
return "id:" + id + " name:" + name + " attack:" + attack;
}
}
[XmlRoot("Players")]
public class XMLPlayerData
{
[XmlElement("player")]
public List<XMLPlayer2> playerDataList = new List<XMLPlayer2>();
}
在使用第二种读取方法时要注意下面的几点下面是xml文件中的内容
下面写一个测试类来测试一下是否正确读取,此处用按键A来调用保存功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class XMLTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//XMLManager.Instance.LoadDataFromXML(Application.streamingAssetsPath + "/PlayerXml.xml");
XMLManager.Instance.LoadDataFromXml2(Application.streamingAssetsPath + "/PlayerXml2.xml");
for (int i = 0; i < XMLManager.Instance.playerData.playerDataList.Count; i++)
{
Debug.Log(XMLManager.Instance.playerData.playerDataList[i]);
}
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
XMLManager.Instance.SaveXml(Application.streamingAssetsPath + "/SavaXmlTest.xml");
Debug.Log("保存成功!");
}
}
}
运行时我们在Console控制台中看到如下效果,可以说明读取和保存是没有问题的
三.读取txt文档
下面是TXTManager类中的内容
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
public class TXTManager
{
static TXTManager instance;
private TXTManager()
{
}
public static TXTManager Instance
{
get
{
if (instance == null)
instance = new TXTManager();
return instance;
}
}
public List<TXTPlayer> playerDataList = new List<TXTPlayer>();
public void LoadDataFromTxt(string path)
{
FileStream fileStream = new FileStream(path, FileMode.Open);
StreamReader sr = new StreamReader(fileStream);
string content = sr.ReadToEnd();
GetDataFromTxt(content);
//关闭文件流
sr.Close();
fileStream.Close();
}
void GetDataFromTxt(string content)
{
string[] rows = content.Split('\r'); //内容分行
string[] title = rows[0].Split(','); //标题行
for (int i = 1; i < rows.Length; i++)
{
string[] curRow = rows[i].Split(',');
TXTPlayer player = new TXTPlayer();
for (int j = 0; j < curRow.Length; j++)
{
switch (title[j])
{
case "id":
player.id = int.Parse(curRow[j]);
break;
case "name":
player.name = curRow[j];
break;
case "hp":
player.hp = int.Parse(curRow[j]);
break;
default:
break;
}
}
playerDataList.Add(player);
}
}
}
public class TXTPlayer
{
public int id;
public string name;
public int hp;
public override string ToString()
{
return "id:" + id + " name:" + name + " hp:" + hp;
}
}
写一个测试类来测试能否正确读取
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TXTTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
TXTManager.Instance.LoadDataFromTxt(Application.streamingAssetsPath + "/Player.txt");
for (int i = 0; i < TXTManager.Instance.playerDataList.Count; i++)
{
Debug.Log(TXTManager.Instance.playerDataList[i]);
}
}
}
以下是txt文本中的内容和我们读取的结果,可以清晰的看到,读取的结果和文本中的内容是一致的
四.总结
以上测试时测试脚本挂在了主相机身上,当然,挂在谁身上不重要。用于测试的文本放在了特殊文件夹StreamingAssets下面,当然,放在哪里也不重要,路径对了就可以。