目前unity常见存档和读档有几种方式,也就是常见的存储数据的方式(注意存档和读档都是针对单机游戏而言的,角色信息,道具信息,关卡情况等)
Unity存档的方式大概分为这两大类
图片来源自siki学院
图片来源自siki学院
第一种:Player Prefs,这是一种键值对的形式,也就是说需要一个键和一个值,键就是用来存放值的,它是储存在注册表中的,由于注册表有限制,并且不安全数据容易被修改,因此常用改方法储存用户设置如音量大小,按键设置等。
使用方法也比较简单,因为是Unity自带的API所以可以直接在脚本中使用,在使用时也比较简单,该类提供了三种方法写入注册表,
分别是PlayerPrefs.SetInt(), PlayerPrefs.SetFloat(),PlayerPrefs.SetString();
void Start()
{
//这三个是写入注册表
PlayerPrefs.SetInt("IsOn", 2);//"IsOn"是键,1是值,它整个是放在注册表中的
PlayerPrefs.SetFloat("Voice", 0.5f);
PlayerPrefs.SetString("Name", "张三");
PlayerPrefs.Save(); //直接调用Set相关方法 只会把数据存到内存里
//当游戏结束时,unity会自动把数据存到硬盘中
//如果游戏在运行过程中崩溃,数据不会存储到硬盘中
//只要调用了该方法,数据就会立即保存。
//这三个是获取
//PlayerPrefs.GetInt("IsOn",0);这样的意思是获取键IsOn对应的值,如果IsOn键没有就返回0
Debug.Log(PlayerPrefs.GetInt("IsOn"));
Debug.Log(PlayerPrefs.GetFloat("Voice"));
Debug.Log(PlayerPrefs.GetString("Name"));
//判断数据是否存在:
if (PlayerPrefs.HasKey("IsOn"))
{
Debug.Log("数据存在");
}
//删除指定键值对:
PlayerPrefs.DeleteKey("year");
//删除所有存储信息:
PlayerPrefs.DeleteAll();
}
第二种:Binary(二进制):在存储较为复杂的数据,例如关卡信息,得分情况,剩余的子弹数量等公众信息时,可以将需要保存的信息都放在一个Save类中,这样就不用像写文档的形式分开存储(久而久之有可能会忘记数据对应的具体是什么),也比直接放在注册表中的功能要强大(毕竟注册表值存储三种数据类型),因此我们都会用存储类的对象的形式来储存数据(XML,Json同理)
既然要以对象的方式来存储数据,那么首先就需要创建一个新类专门用作储存数据,随后使用BinaryFormatter类将该类序列化后存入硬盘中
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]//注意命名空间
public class Save //这是Save类
{
//需要存储的具体信息根据自己的要求编写,这里只是举例
internal int Score;//得分
internal int PlayerLevel;//等级
internal string PlayerSikll;//技能
internal int PlayerHp;//血量
internal int PlayerAp;//蓝量
}
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;//引入二进制转换器的命名空间
using UnityEngine;
using System.IO;
public class BinarySave : MonoBehaviour
{
void SaveFun()//保存函数,也就是将Save对象转换为字节流的过程
{
Save BinarySaveObject = new Save();//声明Save对象,记录当前的游戏状态
BinarySaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
BinarySaveObject.PlayerHp = 5000;
BinarySaveObject.PlayerLevel = 9;
BinarySaveObject.PlayerSikll = "万雷诀";
BinaryFormatter binaryFormatter = new BinaryFormatter();//这相当于一个二进制转换器
FileStream fs = File.Create(Application.dataPath + "/StreamingFile" + "/BinaryTxt");//创建就一个文件流
binaryFormatter.Serialize(fs, BinarySaveObject);//用二进制转换器的序列化方法把Save对象序列化,参数:创建的文件流和需要序列化的对象
fs.Close();//关闭流
}
void LoadFun()//读档函数
{
if(File.Exists(Application.dataPath + "/StreamingFile" + "/BinaryTxt"))//这里最好还是判断文件是否存在
{
//二进制转换器
BinaryFormatter bf = new BinaryFormatter();
//打开一个文件流
FileStream fs = File.Open(Application.dataPath + "/StreamingFile" + "/BinaryTxt", FileMode.Open);
//用反序列化将文件流转换为对象
Save save = (Save)bf.Deserialize(fs);
fs.Close();
Debug.Log(save.PlayerAp);//这里同样可以写函数返回值类型为Save类
Debug.Log(save.PlayerHp);
Debug.Log(save.PlayerLevel);
Debug.Log(save.PlayerSikll);
}
}
private void Start()
{
SaveFun();
LoadFun();
}
}
第三种:XML
学习XML之前先了解XML的大概格式,用一张例图应该就能明白文章来源:https://www.toymoban.com/news/detail-467544.html
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;//引入头文件
using UnityEngine;
public class XmlSave : MonoBehaviour
{
void Save()//存档函数
{
Save XmlSaveObject = new Save();
XmlSaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
XmlSaveObject.PlayerHp = 5000;
XmlSaveObject.PlayerLevel = 9;
XmlSaveObject.PlayerSikll = "万雷诀";
XmlSaveObject.Score = 45;
string path = Application.dataPath + "/StreamingFile" + "/ByXml.json";//这是保存的路径
//创建Xml文档,首先要有xml的文档才能操作
XmlDocument xmlDoc = new XmlDocument();
//创建根节点,也就是最外层的节点,这里就以Save对象为例
XmlElement root = xmlDoc.CreateElement("Save");//用xml文档创建
//设置根节点的值,对象名字为XmlSaveObject
root.SetAttribute("name", "XmlSaveObject");
//这里同样可以写成方法
//1.创建子节点,2.并添加其内容,也就是对象中的各个字段并赋值,3.再将其添加到父节点中
XmlElement PlayerAp = xmlDoc.CreateElement("PlayerAp");//这是创建子节点
PlayerAp.InnerText = XmlSaveObject.PlayerAp.ToString();//这是为子节点添加内容
root.AppendChild(PlayerAp);//这是将子节点添加进父节点中
XmlElement PlayerHp = xmlDoc.CreateElement("PlayerHp");
PlayerHp.InnerText = XmlSaveObject.PlayerHp.ToString();
root.AppendChild(PlayerHp);
XmlElement PlayerLevel = xmlDoc.CreateElement("PlayerLevel");
PlayerLevel.InnerText = XmlSaveObject.PlayerLevel.ToString();
root.AppendChild(PlayerLevel);
XmlElement PlayerSikll = xmlDoc.CreateElement("PlayerSikll");
PlayerSikll.InnerText = XmlSaveObject.PlayerSikll.ToString();
root.AppendChild(PlayerSikll);
XmlElement Score = xmlDoc.CreateElement("Score");
Score.InnerText = XmlSaveObject.Score.ToString();
root.AppendChild(Score);
xmlDoc.AppendChild(root);//这是设置root为根
xmlDoc.Save(path);//将xml文档保存在指定路径
}
void Load()//加载函数
{
string path = Application.dataPath + "/StreamingFile" + "/ByXml.json";
if (File.Exists(path))//判断文件是否存在
{
Save XmlSaveObject = new Save();//创建对象
//加载XML文档
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path);//将硬盘中的xml文档加载到刚创建的xmlDoc中
//通过节点名称来获取元素,结果为XmlNodeList类型
XmlNodeList SaveObejct = xmlDoc.GetElementsByTagName("Save");
//遍历所有的Save(这里因为就一个就遍历一次),并获得Save的子节点和子节点的InnerText
if (SaveObejct.Count != 0)//判断是否为空
{
foreach(XmlNode tempsave in SaveObejct)//这里因为是获得了Save节点,想要里面的子节点就需要像下面这样
{
XmlNode PlayerAp = tempsave.ChildNodes[0];//第一个子节点就是PlayerAp
XmlSaveObject.PlayerAp = XmlConvert.ToInt32(PlayerAp.InnerText);//将第一个子节点的内容赋值给XmlSaveObject对象
XmlNode PlayerHp = tempsave.ChildNodes[1];
XmlSaveObject.PlayerHp = XmlConvert.ToInt32(PlayerHp.InnerText);
XmlNode PlayerLevel = tempsave.ChildNodes[2];
XmlSaveObject.PlayerLevel = XmlConvert.ToInt32(PlayerLevel.InnerText);
XmlNode PlayerSikll = tempsave.ChildNodes[3];
XmlSaveObject.PlayerSikll = PlayerSikll.InnerText;
XmlNode Score = tempsave.ChildNodes[4];
XmlSaveObject.Score = XmlConvert.ToInt32(Score.InnerText);
}
}
Debug.Log(XmlSaveObject.PlayerAp);
Debug.Log(XmlSaveObject.PlayerHp);
Debug.Log(XmlSaveObject.PlayerLevel);
Debug.Log(XmlSaveObject.PlayerSikll);
Debug.Log(XmlSaveObject.Score);
}
}
private void Start()
{
Save();
Load();
}
}
第四种:Json:Json的具体讲解看另一篇,该例子使用的是LitJson文章来源地址https://www.toymoban.com/news/detail-467544.html
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
using System.IO;
public class JsonSave : MonoBehaviour
{
void Save()//保存函数
{
Save JsonSaveObject = new Save();//声明Save对象,记录当前的游戏状态
JsonSaveObject.PlayerAp = 100;//这里是直接对Save对象进行赋值,可以写一个函数然后返回值类型为Save类
JsonSaveObject.PlayerHp = 5000;
JsonSaveObject.PlayerLevel = 9;
JsonSaveObject.PlayerSikll = "万雷诀";
JsonSaveObject.Score = 45;
//这里一定要注意需要字段为public权限,不然会导致转换不成功!!!
string ObjectStr = JsonMapper.ToJson(JsonSaveObject);//将Save对象序列化为Json类型的字符串
string path = Application.dataPath + "/StreamingFile" + "/ByJson.json";//这是保存的路径
//对象被转换成了字符串,这个时候还是需要写进文件中,因此
StreamWriter writer = new StreamWriter(path);//创建文件流
writer.Write(ObjectStr);//写入
writer.Close();//关闭文件流
}
void Load()//加载函数
{
//最好做下判断文档是否存在,这里省略了
string path = Application.dataPath + "/StreamingFile" + "/ByJson.json";//这是想打开的文件路径
StreamReader reader = new StreamReader(path);//创建读取的文件流
string ObjectStr = reader.ReadToEnd();//将文本文件中的内容全部读取到字符串中,(json格式其实就算字符串类型)
reader.Close();//关闭流
Save JsonSaveObject = JsonMapper.ToObject<Save>(ObjectStr);//将json格式转化成对象
//注意这里其实也可以不用读取流的方法,可以直接将json文件放在Resources文件夹下,因为文本在unity中时TextAssets类型,可以直接通过Resources来加载json文件
Debug.Log(JsonSaveObject.PlayerAp);
Debug.Log(JsonSaveObject.PlayerHp);
Debug.Log(JsonSaveObject.PlayerLevel);
Debug.Log(JsonSaveObject.PlayerSikll);
Debug.Log(JsonSaveObject.Score);
}
private void Start()
{
Save();
Load();
}
}
到了这里,关于Unity游戏存档与读档的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!