Unity 保存数据 PlayerPrefs Json

参考
持久性数据:保存游戏状态与设置
Unity中游戏存档方式
简单的介绍几种在unity中对数据的存储和读档的方法!

一、PlayerPrefs

PlayerPrefs并非是为保存游戏状态而开发的,但我们将讨论其在数据保存中的实用性。PlayerPrefs可在多次游戏之间存储玩家的图像质量、音量或其他非必要数据,将偏好设置储存为一个单独的文件(存储路径因操作系统而异,通常位于无访问限制、由系统托管的文件中)。存储数据通常为简单的键值对,且因其易于访问,所以并不能防止居心叵测的家伙修改文件,又因位于系统文件夹下(如“文档”、“桌面”),很有可能会被意外删除。

PlayerPrefs只需要几行代码便可完成应用,但仅支持Float(浮点数)、Int(整数)和String(字符串)类型的值,从而导致大体量复杂对象的序列化非常困难。当然我们可以将所有数据都转换成支持的数据类型,但在有更好的工具方法时,我并不建议大家这么做。

最后,所有PlayerPrefs会被Unity程序存储在一个文件中,而存档或云存档需要我们在多个路径上储存、接收数据,所以它并不适合处理多个存档。

public void SavePrefs()
{
    PlayerPrefs.SetInt("Volume", 50);
    PlayerPrefs.Save();
}
public void LoadPrefs()
{
    int volume = PlayerPrefs.GetInt("Volume", 0);
}

更多API可以参考官方文档:
https://docs.unity3d.com/cn/2019.4/ScriptReference/PlayerPrefs.html

  • 优点:上手简单,存储方便,不用考虑内部实现,适合做小游戏的数据存档(网上一搜,发现很多网友都是用的这种方式。
  • 缺点:只支持基本数据类型,无法存储一个类,数组,集合,字典等。不过肯定是可以用一个框架来实现自动赋值的,只是感觉更麻烦一点。
二、JSON

JSON是一种可读性较高的数据格式,可被人及机器理解——这可以是优点,也能是缺点。优点在于开发者可以更轻松地调试存档、创建新数据进行测试,但另一方面,玩家也能也很容易地读取和修改数据。如果游戏具备mod模组功能,则便于读取和修改的数据会非常有用,但其并不利于反作弊。不同的用例有不同的需求,而这类格式上的优缺点正是开发者制定多种数据格式的原因。

JSON作为标准化的数据格式广泛应用到了各种应用程序中,市面上的各色平台都对其有深层次支持,方便了多平台游戏的开发。JSON起初是作为网页浏览器的通信协议而开发的,本质上非常适合用于发送网络数据,也因此很适合用于从服务器后端发送和接收数据。

1.JsonUtility

https://docs.unity3d.com/cn/current/Manual/JSONSerialization.html

JsonUtility是Unity内置的JSON数据序列化和反序列化API。它与PlayerPrefs一样应用简单,但数据本身必须手动保存在文件中或通过网络保存。在有多个存档时,存档可以手动保存到不同的路径之下。而为了方便存档,我编写了一个文件管理器,在示例代码库中免费提供下载。

https://github.com/UnityTechnologies/UniteNow20-Persistent-Data

请注意,JsonUtility并不具备JSON的全部功能,习惯使用JSON数据的用户会发现一些功能缺失。JsonUtility出于设计目的舍弃了部分功能,也因此比其他.NET JSON解决方案更快、更高效。

JsonUtility与其它Unity内置序列化程序一样有一定的限制——即检视器中无法序列化的字段也无法序列化为JSON。此类问题可以借助Plain Old Data类型(即PODS)解决,在保存时将运行时数据类型转换为POD,再将其保存到磁盘。必要时还可使用自定义序列化回应(custom serialization callbakcs)来支持Unity序列化程序默认不支持的数据类型。

自定义序列化官方文档:
https://docs.unity3d.com/cn/current/Manual/script-Serialization-Custom.html

2.EditorJsonUtility

https://docs.unity3d.com/2020.2/Documentation/ScriptReference/EditorJsonUtility.html

在JsonUtility家族中,EditorJsonUtility是另一个实用的工具。JsonUtility本身适用于MonoBehaviour或ScriptableObject对象,而EditorJsonUtility适用于所有Unity引擎的数据类型,我们可以在Unity编辑器中用JSON表示任意对象,也可以反之用JSON文件创建资产。

优点:

  • 简单轻量
  • 可以满足你要序列化的几乎任何类型数据(除了float必须用double来存)
  • 如果要升级版本,可以任意删除之前的字段而不会出现不能解析的情况;可以新增字段且采用你在类中直接赋的值(不用像c#序列化那样手动赋值了)。

缺点:

  • 相对PlayerPrefs来说,引入了一个50kb左右的dll。
  • 不能序列化float类型。
  • 不支持更改字段名。如果更改了,就相当于是两个操作,即删除之前的并新增加一个(这一点很重要)。
三、其他方式
1.EasySave

EasySave插件链接

EasySave是Unity Asset Store上一个广受欢迎的插件,让用户无需编写代码即可保存数据,对初学者尤其友好。插件还具备功能强大、使用灵活的API,也能满足高级用户的需求。软件功能全面、开箱即用,绝对让你物超所值。

2.JSON.Net

JSON.Net

JSON.Net是兼容所有DotNet平台、免费开源的JSON应用,并且具备内置JsonUtility所舍弃的功能。标准版本的JSON.Net并不支持所有Unity平台,但Unity Asset Store上的修改版扩充了平台支持。

3.XML

XML是数据格式类似与JSON,具备较高的可读性,以及命名空间这类实用功能。DotNet具备对XML的内置支持。
优点:

  • 序列化出来的数据直观,可以序列化类和类中的对象。
  • 升级版本后,如果新增了字段,则自动采用你在类中赋给该变量的值。
  • 升级版本后,如果删除了之前的字段,则自动忽略之前的字段,而不会像c#序列化一样报错,

缺点:

  • 不能序列化字典,二维数组以上的数据
  • 比Json更占空间,且引入的dll也更大
4.BinaryFormatter

BinaryFormatter属于DotNet库的一份子,可用于将对象直接储存为二进制文件。但BinaryFormatter带有危险的安全漏洞,所以请不要使用BinaryFormatter。点击下方链接详细了解软件的安全风险。

安全风险

BinaryFormatter

5.c#序列化

优点:除了静态类型和抽象类型以及类必须标记为[Serializable]的(其实这个不是什么问题了),其他的都可以被序列化:类,数组,集合,字典,类及其子类等。而且序列化之后你也看不懂是什么鬼(哈哈)~~。

缺点:

  • 不会调用要序列化类的构造函数(当然可以通过实现ISerializable和IDeserializationCallback接口来实现在序列化和反序列化之前对数据的处理,所以这个不是我放弃它的重点)。
  • 在升级版本后,新增一个字段也只是采用系统默认值,而不是我在类中直接赋的值,这导致我需要自己去比较当前版本和之前的每一个版本的版本号,然后再挨个处理每个以前版本的升级,就意味着当前是第N次更新,我要做N-1次if判断并手动赋值(这段话是结合自己的项目记录的,当然也就我看得懂了^^)。
  • 而让我放弃它的最终原因是,在升级版本后,如果删除了之前的一个字段,则无法正确解析(反序列化),这种情况就最不能容忍了。我不敢冒这样的风险,保证以后的版本不会删除其中一个字段。或许你会想到“你可以保留啊,然后不管它就是了”,不过鉴于我有个超追求完美的boss,只好放弃。毕竟这还不如XML。
四、数据安全

在涉及安全性问题时,大多数人会首先想到数据加密。然而当数据存储在玩家设备上时,数据加密容易被破解。即便加密数据未被破解,用户也可以使用各色免费工具直接在内存中修改数据。换句话说,我们能断言存储在本地的数据都不安全。

如果想要实现真正的数据安全,最好的选择是将数据保存在用户不能触及的服务器上,应用本身也不能向服务器直接发送数据,以防用户修改。相反的,应用只能向服务器发送指令,由服务器来更改数据、将结果发送回应用。因此我们最好尽早明确数据安全的影响,确定项目的数据结构。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容