You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity使用BinaryFormatter保存自定义类列表时序列化报错如何解决

错误原因

BinaryFormatter序列化要求所有参与序列化的自定义类型都必须标记[System.Serializable]特性。你已为PlayerData添加了该特性,但PlayerData中存储的List<GunScript>的元素类型GunScript未标记可序列化,因此序列化触发报错。
如果GunScript是继承自MonoBehaviour的脚本,即使添加序列化特性也无法正常序列化,因为MonoBehaviour类型本身不支持BinaryFormatter的二进制序列化规则。

解决方案

情况1:GunScript为普通非MonoBehaviour类

直接给GunScript类添加[System.Serializable]特性即可:

[System.Serializable]
public class GunScript
{
    // 你原本的GunScript字段和逻辑
}

情况2:GunScript继承自MonoBehaviour(绝大多数情况)

不要直接序列化MonoBehaviour实例,单独定义纯数据类存储枪支需要持久化的属性,仅序列化纯数据类:

  1. 定义枪支纯数据类
[System.Serializable]
public class GunSaveData
{
    // 仅填写你需要保存的枪支属性,例如:
    public int gunId;
    public int damage;
    public int remainingBullet;
    public bool isUnlocked;
}
  1. 修改PlayerData中的列表类型
[System.Serializable]
class PlayerData
{
    public int money;
    public int xp;
    public float time;
    public int laval;
    public int maxXp;
    public int howMuchUpMaxXp;
    // 把List<GunScript>替换为纯数据类列表
    public List<GunSaveData> gun = new List<GunSaveData>();
}
  1. 修改Save逻辑,把运行时的GunScript属性转存为纯数据
for (int i = 0; i < gun.Count; i++)
{
    GunSaveData saveData = new GunSaveData();
    // 从GunScript实例取出需要保存的属性赋值给saveData
    saveData.gunId = gun[i].gunId;
    saveData.damage = gun[i].damage;
    saveData.remainingBullet = gun[i].remainingBullet;
    saveData.isUnlocked = gun[i].isUnlocked;
    data.gun.Add(saveData);
}
  1. Load完成后,把读取到的GunSaveData列表属性赋值回场景中的GunScript实例即可。

额外优化建议

BinaryFormatter存在已知的安全漏洞,微软官方已不推荐使用,Unity项目中更推荐使用JsonUtility、Newtonsoft Json进行数据序列化,适配性更高、排查问题更简单。

内容的提问来源于stack exchange,提问作者יאיר מרקובסקי

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:15:06