存档
参考
使用没有存档的软件,就像吃饭不给容器一般。
故存档必然是极为重要的。
下面介绍Unity的几种存档方式。
代码出处
Part.1——PlayerPrefs
应该是最简单的存档方式。
但局限性也是显然的,只能存储int, float, string
三种类型,就像在文件中存储了三个map <string, int / float / string>
。
PlayerPrefs.SetInt("田所浩二", 114514); // 存
PlayerPrefs.SetString("涛哥", "原神");string players_id = PlayerPrefs.GetString("涛哥"); // 读
Part.2——存储数据序列化
分为三种:二进制方法、XML方法、JSON方法,各有千秋。
大体就是
序列化 对象 -> 字节流
反序列化 字节流 -> 对象
先创建一个Save类,用于记录需要保存的东西
public class Save
{public List <string> HZOI_name = new List <string>();public int id;
}
1. 二进制方式
使用二进制文件进行序列化与反序列化
private void Save_By_Bin()
{Save save = Create_Save();BinaryFormatter bf = new BinaryFormatter(); // 创建二进制格式化进程FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/byBin.txt"); // 创建文件流bf.Serialize(fileStream, save);fileStream.Close(); // 关闭if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")){Debug.Log("保存成功");}
}private void Load_By_Bin()
{if(File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")){BinaryFormatter bf = new BinaryFormatter(); // 创建二进制格式化进程FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/byBin.txt", FileMode.Open());Save save = (Save)bf.Deserialize(fileStream);fileStream.Close();Set_Game(save);Debug.Log("成功");}else{Debug.Log("What are you doing?");}
}
2. JSON方法
使用JSON进行序列化与反序列化
//JSON:存档和读档
private void SaveByJson()
{Save save = Create_Save();string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";//利用JsonMapper将save对象转换为Json格式的字符串string saveJsonStr = JsonMapper.ToJson(save);//将这个字符串写入到文件中//创建一个StreamWriter,并将字符串写入文件中StreamWriter sw = new StreamWriter(filePath);sw.Write(saveJsonStr);sw.Close();if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")){Debug.Log("保存成功");}
}private void LoadByJson()
{ string filePath = Application.dataPath + "/StreamingFile" + "/byJson.json";if(File.Exists(filePath)){//创建一个StreamReader,用来读取流StreamReader sr = new StreamReader(filePath);//将读取到的流赋值给jsonStrstring jsonStr = sr.ReadToEnd();//关闭sr.Close();//将字符串jsonStr转换为Save对象Save save = JsonMapper.ToObject<Save>(jsonStr);SetGame(save);//将保存的信息类初始游戏Debug.Log("成功");}else{Debug.Log("What are you doing?");}
}
XML方法
//XML:存档和读档--要根据XML文件的结点结构进行操作
private void SaveByXml()
{Save save = CreateSaveGO();//创建XML文件的存储路径string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";//创建XML文档XmlDocument xmlDoc = new XmlDocument();//创建根节点,即最上层节点XmlElement root = xmlDoc.CreateElement("save");//设置根节点中的值root.SetAttribute("name", "saveFile1");//创建XmlElementXmlElement target;XmlElement targetPosition;XmlElement monsterType;//遍历save中存储的数据,将数据转换成XML格式for(int i = 0; i < save.livingTargetPositions.Count; i++){target = xmlDoc.CreateElement("target");targetPosition = xmlDoc.CreateElement("targetPosition");//设置InnerText值targetPosition.InnerText = save.livingTargetPositions[i].ToString();monsterType = xmlDoc.CreateElement("monsterType");monsterType.InnerText = save.livingMonsterTypes[i].ToString();//设置节点间的层级关系 root -- target -- (targetPosition, monsterType)target.AppendChild(targetPosition);target.AppendChild(monsterType);root.AppendChild(target);}//设置射击数和分数节点并设置层级关系 xmlDoc -- root --(target-- (targetPosition, monsterType), id, score)XmlElement id = xmlDoc.CreateElement("id");id.InnerText = save.id.ToString();root.AppendChild(id);xmlDoc.AppendChild(root);xmlDoc.Save(filePath);if (File.Exists(Application.dataPath + "/StreamingFile" + "/byBin.txt")){Debug.Log("保存成功");}
}private void LoadByXml()
{string filePath = Application.dataPath + "/StreamingFile" + "/byXML.txt";if(File.Exists(filePath)){Save save = new Save();//加载XML文档XmlDocument xmlDoc = new XmlDocument();xmlDoc.Load(filePath);//通过节点名称来获取元素,结果为XmlNodeList类型XmlNodeList targets = xmlDoc.GetElementsByTagName("target");//遍历所有的target节点,并获得子节点和子节点的InnerTextif(targets.Count != 0){foreach(XmlNode target in targets){XmlNode targetPosition = target.ChildNodes[0];int targetPositionIndex = int.Parse(targetPosition.InnerText);//把得到的值存储到save中save.livingTargetPositions.Add(targetPositionIndex);XmlNode monsterType = target.ChildNodes[1];int monsterTypeIndex = int.Parse(monsterType.InnerText);save.livingMonsterTypes.Add(monsterTypeIndex);}}XmlNodeList id = xmlDoc.GetElementsByTagName("id");int shootNumCount = int.Parse(id[0].InnerText);save.id = shootNumCount;SetGame(save);//将保存的信息类初始游戏//TODO: 提示存档不存在或为空,读取成功Debug.Log("成功");}else{Debug.Log("What are you doing?");}
}
Part.3 总结
二进制方法:简单简洁,但可读性极差
JSON方法:可读性好,感觉比较符合人类直觉
XML:冗长,可读性好(?没感觉可读性太好,可能是我太蒻了呜呜呜)