首页 > 其他分享 >Unity数据持久化——序列化/二进制/Json/PlayerPrefs

Unity数据持久化——序列化/二进制/Json/PlayerPrefs

时间:2024-07-29 22:54:16浏览次数:14  
标签:存储 字节 Unity Json PlayerPrefs 序列化 string

序列化

序列化是指把对象转换为字节序列的过程,而反序列化是指将字节序列恢复为对象的过程。
序列化最主要的用途就是传递对象和保存对象。

在Unity中保存和加载、prefab、Scene、Inspector窗口、实例化预制体等都使用了序列化和反序列化。下面是一个序列化和反序列化的例子。

[Serializable]
public class Player
{
    public int coin = 0;
    public int money = 0;
    public string name = "";
}

Player player = new Player();
player.coin = 1;
player.money = 10;
player.name = "XiaoMing";
//序列化
using (Stream stream = new FileStream("data.bin", FileMode.Create, FileAccess.Write, FileShare.None)) {
    IFormatter formatter = new BinaryFormatter();
    //序列化对象 生成2进制字节数组 写入到内存流当中
    formatter.Serialize(stream, player);
    stream.Close();
}

//反序列化
using (Stream stream2 = new FileStream("data.bin", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    Console.WriteLine(stream2.ToString());
    IFormatter formatter2 = new BinaryFormatter();
    Player player2 =(Player)formatter2.Deserialize(stream2);
    Console.WriteLine(player2.coin);
    Console.WriteLine(player2.money);
    Console.WriteLine(player2.name);
    stream2.Close();
}

补充:使用using更安全的使用文件流对象
using关键字重要用法
using (申明一个引用对象)
{
使用对象
}
无论发生什么情况,当using语句块结束后,会自动调用该对象的销毁方法,避免忘记销毁或关闭流。using是一种更安全的使用方法。目前我们对文件流进行操作,为了文件操作安全,都用using来进行处理最好。

二进制

二进制文件的读写本质,就是通过将各类型变量转换为字节数组,将字节数组直接存储到文件中,一般人是看不懂存储的数据的,不仅可以节约存储空间,提升效率,还可以提升安全性,而且在网络通信中我们直接传输的数据也是字节数据(二进制数据)。

二进制持久化的一个主要应用就是序列化和反序列化。这里再补充一些常用用法。

  1. 变量的本质是2进制,在内存中都以字节的形式存储着,通过sizeof方法可以看到常用变量类型占用的字节空间长度
    sizeof(int)
  2. C#提供了一个公共类BitConverter可以将各类型数据和字节数据相互转换
  • 将各类型转字节
    byte[] bytes = BitConverter.GetBytes(256);
  • 字节数组转各类型
    int i = BitConverter.ToInt32(bytes, 0);
  1. C#中有一个专门的编码格式类Encoding可以将字符串和字节数组进行转换
  • 将字符串以指定编码格式转字节
    byte[] bytes2 = Encoding.UTF8.GetBytes("abc");
  • 字节数组以指定编码格式转字符串
    string s = Encoding.UTF8.GetString(bytes2);

Json

1. JsonUtility
JsonUtility是Unity自带的用于解析Json的工具类。它可以将内存中对象序列化为Json格式的字符串,将Json字符串反序列化为类对象。

用法:

//将对象序列化为Json格式的字符串
public string ToJson()
{
    return JsonUtility.ToJson(this);
}
//将Json字符串转化为类对象
public GameData FromJson(string json)
{
    return JsonUtility.FromJson<GameData>(json);
}

注意:

  • float序列化时看起来会有一些误差
  • 自定义类需要加上序列化特性[System.Serializable]
  • 想要序列化私有变量 需要加上特性[SerializeField]
  • JsonUtility不支持字典
  • JsonUtility不能直接将数据反序列化为数据集合
  • JsonUtility存储null对象不会是null 而是默认值的数据
  • Json文档编码格式必须是UTF-8
2. LitJson
LitJson是一个第三方库,用于处理Json的序列化和反序列化。

用法:

//将对象序列化为Json格式的字符串
public string ToJson()
{
    return JsonMapper.ToJson(this);
}
//将Json字符串转化为类对象
public GameData ToObject(string json)
{
    return JsonMapper.ToObject<GameData>(json);
}

注意:

  • LitJson无需加特性
  • LitJson不支持私有变量
  • LitJson支持字典序列化反序列化
  • LitJson可以直接将数据反序列化为数据集合
  • LitJson反序列化时 自定义类型需要无参构造
  • LitJson可以准确的保存null类型
  • Json文档编码格式必须是UTF-8

PlayerPrefs

PlayerPrefs是Unity用于存储和读取玩家数据的一个公共类。

PlayerPrefs的数据存储类似于键值对存储,一个键对应一个值,并且它的key是唯一的。它提供了存储3种数据的方法 int float string
键: string类型
值:int float string 对应3种API

存储相关
PlayerPrefs.SetInt("myAge", 22);
PlayerPrefs.SetFloat("myHeight", 172.5f);
PlayerPrefs.SetString("myName", "abc");

直接调用Set相关方法只会把数据存到内存里,当游戏结束时,Unity会自动把数据存到硬盘中。如果游戏不是正常结束的,而是崩溃,数据是不会存到硬盘中的。所以只要调用PlayerPrefs.Save();,数据就会马上存储到硬盘中。

读取相关
int age = PlayerPrefs.GetInt("myAge");
float height = PlayerPrefs.GetFloat("myHeight");
string name = PlayerPrefs.GetString("myName");

//如果找不到myAge对应的值 就会返回函数的第二个参数 默认值,其他两个API也是如此
age = PlayerPrefs.GetInt("myAge", 100);

//判断数据是否存在
PlayerPrefs.HasKey("myName");
删除相关
//删除指定键值对
PlayerPrefs.DeleteKey("myAge");
//删除所有存储的信息
PlayerPrefs.DeleteAll();

PlayerPrefs在不同平台存储的位置是不一样的。
Windows平台是存储在注册表中,位置是HKCU\Software\公司名称\产品名称,其中公司和产品名称是在“Project Settings”中设置的名称。
Android平台是存储在/data/data/包名/shared_prefs/pkg-name.xml
IOS平台是存储在/Library/Preferences/com.公司名.项目名.plist

标签:存储,字节,Unity,Json,PlayerPrefs,序列化,string
From: https://blog.csdn.net/2403_83681139/article/details/140783049

相关文章

  • Laravel序列化解码:深入Eloquent模型的序列化机制
    Laravel序列化解码:深入Eloquent模型的序列化机制引言Laravel作为一门优雅的PHPWeb开发框架,提供了许多便利的功能来简化开发过程。其中一个强大而易用的功能便是模型的序列化。序列化是将对象状态转换为可以存储或传输的格式的过程。在Laravel中,EloquentORM支持模型的自......
  • unity游戏源码和配套教程:三维的美好场景,完全免费和开源,教程完整详细,适合初学者入门
    源码(含配套教程)在夸克网盘(完全免费,完全开源,完整详细):夸克网盘分享夸克网盘是夸克推出的一款云服务产品,功能包括云存储、高清看剧、文件在线解压、PDF一键转换等。通过夸克网盘可随时随地管理和使用照片、文档、手机资料,目前支持Android、iOS、PC、iPad。https://pan.quark.cn/s/......
  • Java中的反序列化漏洞及其防护措施
    Java中的反序列化漏洞及其防护措施大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨Java中的反序列化漏洞及其防护措施。反序列化漏洞是由不安全的对象反序列化引起的,攻击者可以通过精心构造的恶意数据流进行攻击,导致远程代码执行和其他安全......
  • 自写Json转换工具
    前面写了简单的API测试工具ApiTools,返回的json有时需要做很多转换,于是开发了这个工具。功能包括1、json字符串转为表格,可以直观的展示,也可以复制,并支持转换后的表格点击列头进行排序,比较方便地定位数据。2、表格转为EXCEL,就是导出Excel文件,支持2003和2007格式,即xls和xlsx。......
  • Unity GameObject学习笔记
    GameObject成员变量GameObject静态方法//准备用来克隆的对象//1.直接是场景上的某个对象//2.可以是一个预制体对象publicGameObjectMyobj;#region知识点二GameObject中的静态方法创建自带几何体只要得到了一个GameObject对象我就......
  • Json 序列化、反序列化;重复或循环使用时注意事项
    Json序列化问题publicclassTest2{publicstaticvoidmain(String[]args)throwsJsonProcessingException{ObjectMapperobjectMapper=newObjectMapper();objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);Plug......
  • 使用“marshmallow-sqlalchemy”时发生错误,异常:反序列化需要会话
    使用marshmallow-sqlalchemy反序列化对象,但出现错误。我已经通过了session对象,也就是数据库DB,但是还是没有效果,这个问题已经2天了,依然无法解决。my_db.pyfromsqlalchemyimportcreate_enginefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.o......
  • unity2D游戏开发11游戏背包开发
    背包存放游戏物品的地方在Hiearchy右键UI|Canvas,删除EventSystem,将Canvas重命名为InventoryObject设置属性右键InventoryObject,选择CreateEmpty,重命名为InventoryBackgroun,添加HorizontalLayoutGroup,HorizntalLayoutGroup将自动排列所有子对象,使他们水平......
  • js实现JSON数据根据某个字段排序
    1、js含有内置的sort()方法该方法是按字母顺序对数组进行排序的即按照字符编码进行排序,当数组中元素为数字类型时,排序结果与我们设想的完全不同,因为默认是按照字符编码的顺序进行排序的2、实现/**@description根据某个字段实现对json数组的排序*@para......
  • 将 JSON 发送到 Flask,request.args 与 request.form
    我的理解是,request.argsFlask中包含来自GET请求的URL编码参数,而request.form包含POST数据。我很难理解为什么在发送POST请求时,尝试使用request.form访问数据会返回400错误,但是当我尝试使用request.args......