Unity序列化之XML,JSON--------合成与解析
简单例子(SiKi学院教程):
1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 [System.Serializable]
6 public class Save{
7
8 //怪物位置和类型
9 public List<int> livingTargetPositions = new List<int>();
10 public List<int> livingMonsterTypes = new List<int>();
11
12 //射击数和分数
13 public int shootNum = 0;
14 public int score = 0;
15 }
Save类--所要存储的数据
1 //创建Save对象并存储当前游戏状态信息
2 private Save CreateSaveGO()
3 {
4 //新建Save对象
5 Save save = new Save();
6 //遍历所有的target
7 //如果其中有处于激活状态的怪物,就把该target的位置信息和激活状态的怪物的类型添加到List中
8 foreach (GameObject targetGO in targetGOs)
9 {
10 TargetManager targetManager = targetGO.GetComponent<TargetManager>();
11 if (targetManager.activeMonster != null)
12 {
13 save.livingTargetPositions.Add(targetManager.targetPosition);
14 int type = targetManager.activeMonster.GetComponent<MonsterManager>().monsterType;
15 save.livingMonsterTypes.Add(type);
16 }
17 }
18 //把shootNum和score保存在Save对象中
19 save.shootNum = UIManager._instance.shootNum;
20 save.score = UIManager._instance.score;
21 //返回该Save对象
22 return save;
23 }
添加当前游戏信息
1 //通过读档信息重置我们的游戏状态(分数、激活状态的怪物)
2 private void SetGame(Save save)
3 {
4 //先将所有的targrt里面的怪物清空,并重置所有的计时
5 foreach(GameObject targetGO in targetGOs)
6 {
7 targetGO.GetComponent<TargetManager>().UpdateMonsters();
8 }
9 //通过反序列化得到的Save对象中存储的信息,激活指定的怪物
10 for(int i = 0; i < save.livingTargetPositions.Count; i++)
11 {
12 int position = save.livingTargetPositions[i];
13 int type = save.livingMonsterTypes[i];
14 targetGOs[position].GetComponent<TargetManager>().ActivateMonsterByType(type);
15 }
16
17 //更新UI显示
18 UIManager._instance.shootNum = save.shootNum;
19 UIManager._instance.score = save.score;
20 //调整为未暂停状态
21 UnPause();
22 }
读档时设置信息
存读档三种方式:
>二进制:
1 //二进制方法:存档和读档
2 private void SaveByBin()
3 {
4 //序列化过程(将Save对象转换为字节流)
5 //创建Save对象并保存当前游戏状态
6 Save save = CreateSaveGO();
7 //创建一个二进制格式化程序
8 BinaryFormatter bf = new BinaryFormatter();
9 //创建一个文件流
10 FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt");
11 //用二进制格式化程序的序列化方法来序列化Save对象,参数:创建的文件流和需要序列化的对象
12 bf.Serialize(fileStream, save);
13 //关闭流
14 fileStream.Close();
15
16
17 //如果文件存在,则显示保存成功
18 if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
19 {
20 UIManager._instance.ShowMessage("保存成功");
21 }
22 }
SaveByBinary
1 private void LoadByBin()
2 {
3 if(File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt"))
4 {
5 //反序列化过程
6 //创建一个二进制格式化程序
7 BinaryFormatter bf = new BinaryFormatter();
8 //打开一个文件流
9 FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open);
10 //调用格式化程序的反序列化方法,将文件流转换为一个Save对象
11 Save save = (Save)bf.Deserialize(fileStream);
12 //关闭文件流
13 fileStream.Close();
14
15 SetGame(save);
16 UIManager._instance.ShowMessage("");
17
18 }
19 else
20 {
21 UIManager._instance.ShowMessage("存档文件不存在");
22 }
23 }
LoadByBinary
>Json
1 //JSON:存档和读档
2 private void SaveByJson()
3 {
4 Save save = CreateSaveGO();
5 string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
6 //利用JsonMapper将save对象转换为Json格式的字符串
7 string saveJsonStr = JsonMapper.ToJson(save);
8 //将这个字符串写入到文件中
9 //创建一个StreamWriter,并将字符串写入文件中
10 StreamWriter sw = new StreamWriter(filePath);
11 sw.Write(saveJsonStr);
12 //关闭StreamWriter
13 sw.Close();
14
15 UIManager._instance.ShowMessage("保存成功");
16 }
SaveByJson
1 private void LoadByJson()
2 {
3 string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";
4 if(File.Exists(filePath))
5 {
6 //创建一个StreamReader,用来读取流
7 StreamReader sr = new StreamReader(filePath);
8 //将读取到的流赋值给jsonStr
9 string jsonStr = sr.ReadToEnd();
10 //关闭
11 sr.Close();
12
13 //将字符串jsonStr转换为Save对象
14 Save save = JsonMapper.ToObject<Save>(jsonStr);
15 SetGame(save);
16 UIManager._instance.ShowMessage("");
17 }
18 else
19 {
20 UIManager._instance.ShowMessage("存档文件不存在");
21 }
22 }
LoadByJson
>Xml
1 //XML:存档和读档
2 private void SaveByXml()
3 {
4 Save save = CreateSaveGO();
5 //创建XML文件的存储路径
6 string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
7 //创建XML文档
8 XmlDocument xmlDoc = new XmlDocument();
9 //创建根节点,即最上层节点
10 XmlElement root = xmlDoc.CreateElement("save");
11 //设置根节点中的值
12 root.SetAttribute("name", "saveFile1");
13
14 //创建XmlElement
15 XmlElement target;
16 XmlElement targetPosition;
17 XmlElement monsterType;
18
19 //遍历save中存储的数据,将数据转换成XML格式
20 for(int i = 0; i < save.livingTargetPositions.Count; i++)
21 {
22 target = xmlDoc.CreateElement("target");
23 targetPosition = xmlDoc.CreateElement("targetPosition");
24 //设置InnerText值
25 targetPosition.InnerText = save.livingTargetPositions[i].ToString();
26 monsterType = xmlDoc.CreateElement("monsterType");
27 monsterType.InnerText = save.livingMonsterTypes[i].ToString();
28
29 //设置节点间的层级关系 root -- target -- (targetPosition, monsterType)
30 target.AppendChild(targetPosition);
31 target.AppendChild(monsterType);
32 root.AppendChild(target);
33 }
34
35 //设置射击数和分数节点并设置层级关系 xmlDoc -- root --(target-- (targetPosition, monsterType), shootNum, score)
36 XmlElement shootNum = xmlDoc.CreateElement("shootNum");
37 shootNum.InnerText = save.shootNum.ToString();
38 root.AppendChild(shootNum);
39
40 XmlElement score = xmlDoc.CreateElement("score");
41 score.InnerText = save.score.ToString();
42 root.AppendChild(score);
43
44 xmlDoc.AppendChild(root);
45 xmlDoc.Save(filePath);
46
47 if(File.Exists(Application.dataPath + "/StreamingFile" + "/byXML.txt"))
48 {
49 UIManager._instance.ShowMessage("保存成功");
50 }
51 }
SaveByXml
1 private void LoadByXml()
2 {
3 string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";
4 if(File.Exists(filePath))
5 {
6 Save save = new Save();
7 //加载XML文档
8 XmlDocument xmlDoc = new XmlDocument();
9 xmlDoc.Load(filePath);
10
11 //通过节点名称来获取元素,结果为XmlNodeList类型
12 XmlNodeList targets = xmlDoc.GetElementsByTagName("target");
13 //遍历所有的target节点,并获得子节点和子节点的InnerText
14 if(targets.Count != 0)
15 {
16 foreach(XmlNode target in targets)
17 {
18 XmlNode targetPosition = target.ChildNodes[0];
19 int targetPositionIndex = int.Parse(targetPosition.InnerText);
20 //把得到的值存储到save中
21 save.livingTargetPositions.Add(targetPositionIndex);
22
23 XmlNode monsterType = target.ChildNodes[1];
24 int monsterTypeIndex = int.Parse(monsterType.InnerText);
25 save.livingMonsterTypes.Add(monsterTypeIndex);
26 }
27 }
28
29 //得到存储的射击数和分数
30 XmlNodeList shootNum = xmlDoc.GetElementsByTagName("shootNum");
31 int shootNumCount = int.Parse(shootNum[0].InnerText);
32 save.shootNum = shootNumCount;
33
34 XmlNodeList score = xmlDoc.GetElementsByTagName("score");
35 int scoreCount = int.Parse(score[0].InnerText);
36 save.score = scoreCount;
37
38 SetGame(save);
39 UIManager._instance.ShowMessage("");
40
41 }
42 else
43 {
44 UIManager._instance.ShowMessage("存档文件不存在");
45 }
46 }
LoadByXml
在Json进行数据转换时报错:JsonException: Max allowed object depth reached while trying to export from type System.Single
是因为数据中有float类型
以下是Json支持的类型