Unity复习学习随笔(11):二进制存储
1. 为什么存档要选二进制:格式选型和性能账
最近在整理自己项目里的存档系统,顺手把二进制存储这块重新过了一遍。很多朋友在做Unity游戏时,第一次接触存档基本都是PlayerPrefs,拿它存点音量设置、金币数量,图个方便。但一旦数据量上来,比如背包里几百件装备、地图上几十个NPC的对话进度、技能树解锁状态,PlayerPrefs那种键值对方式就明显不够用了,而且它本质是明文存储,玩家拿个文本编辑器就能改数据,对做单机养成、卡牌这类游戏来说基本等于没设防。
二进制存储在这个场景下是非常自然的选型。它跟JSON、XML这类文本格式最大的区别在于:写入和读取都是按字节流处理的,不经过字符串序列化和解析那一步,所以数据占用的空间更小,读写速度也更快。我实测过一份有1万个怪物坐标加属性记录的存档,JSON大概要4.5MB,而二进制格式只有1.2MB左右,加载时间也从几百毫秒降到了几十毫秒。对于移动端游戏来说,这差距直接体现在启动速度和内存占用上,玩家感受非常明显。
如果你正在复习Unity基础或者准备面试,二进制存储几乎是必考题。面试官喜欢问“你项目里的存档怎么做的”“为什么不用PlayerPrefs”“JSON和二进制你选哪个,为什么”,这些问题背后其实考的就是对数据序列化的理解深度。这篇随笔不适合纯零基础的人看,但只要你写过几个小Demo、知道C#的基本语法,跟着这篇文章实操一遍,绝对能让你对存档系统的认知上一个台阶。
我计划从最基础的方式入手,一路聊到优化方案、加密处理和跨平台注意事项,最后再分享几个我实际踩过的坑,顺便把搜到的那些报错案例一并解释了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先跑通最小案例:BinaryFormatter快速入门
2.1 序列化和反序列化的核心流程
Unity里最省事的二进制方案就是BinaryFormatter。它是.NET自带的序列化器,能把一个对象整个打包成二进制流,也能从二进制流里恢复出原来的对象。用起来非常简单,核心代码就这几行:
csharp复制using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
// 序列化:对象 -> 字节流 -> 文件
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/save.dat");
bf.Serialize(file, playerData);
file.Close();
注意Serialize方法第一个参数是Stream,第二个参数是要写入的对象。反序列化就是对偶的操作:
csharp复制BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/save.dat", FileMode.Open);
PlayerData data = (PlayerData)bf.Deserialize(file);
file.Close();
这里有个很容易踩的坑:反序列化时类型转换失败是家常便饭。Deserialize返回的是object类型,如果你存档的结构和当前类的定义对不上,或者命名空间改了,直接强转会抛出异常。所以实际项目里我都会给这个类加一层校验,至少把转换包在try-catch里,别让玩家一读档就闪退。
配合[Serializable]特性标记,这个方案几乎零学习成本。比如你定义了一个存档数据结构:
csharp复制[Serializable]
public class PlayerData
{
public string playerName;
public int level;
public float hp;
public List<int> itemIds = new List<int>();
}
直接把整个对象扔给BinaryFormatter,它就能自动递归处理嵌套的List、Dictionary等结构。这背后的原理是反射加递归遍历字段,所以它不关心你类里写了多少字段,只要都标记了[Serializable]就行。这也是BinaryFormatter最大的优点:写起来爽,适合原型验证和教学。
2.2 特性标记与版本兼容的第一次踩坑
这里必须提醒一句:BinaryFormatter并不是完美无缺的。在Unity 2021.3.x之后的版本里,如果你用了它,编辑器会弹一个警告,提示BinaryFormatter serialization is obsolete and not recommended。很多人第一次看到这个警告会慌,以为代码出错了。其实不是错误,只是官方出于安全考虑不建议在新项目里继续用。因为BinaryFormatter在反序列化时存在被恶意构造数据利用的风险,有些服务器项目甚至直接禁用这个类型。
除了安全警告,BinaryFormatter最大的
