mcpField
U
Unity Save System

Unity Save System

github.com/juliankerignard开发852 次安装32 周前更新
代码仓库

关于 Unity Save System

Unity Save System 是面向 Unity 6+ 开发者的保存系统实现指南,涵盖从简单偏好设置到本地与云端混合架构。内容强调原子写入、数据版本迁移、多存档槽和自动保存。

主要功能

  1. 01序列化游戏状态并持久化
  2. 02原子文件写入与备份恢复
  3. 03存档版本管理与迁移
  4. 04多槽位及自动保存
  5. 05UGS 云存档与可选加密

适用场景

  1. 01为 Unity 游戏实现进度存档
  2. 02处理存档格式变更与迁移
  3. 03在暂停或场景切换时自动保存

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/juliankerignard/unity-skills --skill unity-save-system

安装后在 Claude Code 中输入/unity-save-system确认已加载。

附带文件references/save-advanced.mdreferences/save-templates.md

详细介绍

Unity 保存系统

此技能的功能

指导在 Unity 6+ 中实现完整的保存系统:游戏状态序列化、通过原子写入持久化到文件、存档版本控制、多槽位管理、自动保存、云存档(UGS)和可选加密。涵盖从简单的 PlayerPrefs 到本地/云端混合架构。

先决条件

  • Unity 6.0+(Awaitable API)
  • 推荐:使用 Newtonsoft.Json(com.unity.nuget.newtonsoft-json)进行高级序列化
  • 简单场景无需严格依赖(JsonUtility 已足够)

快速入门

  1. 选择格式:JsonUtility(简单)或 Newtonsoft.Json(多态、Dictionary)
  2. 在每个需要保存的组件上创建 ISaveable 接口
  3. 实现 SaveManager,在 Application.persistentDataPath 中执行原子写入
  4. 接入 自动保存(dirty flag + timer + OnApplicationPause)
  5. 测试 保存/加载流程,并编写 EditMode 测试(参见 /unity-test)

决策树

Que sauvegarder ?
|
+-- Preferences utilisateur (volume, langue, bindings) ?
|   +-- Peu de donnees (<1 KB) --> PlayerPrefs
|   +-- Plus structure ----------> JSON dans persistentDataPath
|
+-- Etat de jeu (progression, inventaire, position) ?
|   +-- Slot unique -----------> JSON + ISaveable pattern
|   +-- Multi-slots -----------> SaveManager avec index + slots nommes
|   +-- Donnees volumineuses (>10 MB) --> Format binaire (MemoryPack/MessagePack)
|
+-- Cloud sync ?
|   +-- Unity Gaming Services --> UGS Cloud Save
|   +-- Cross-platform natif --> Platform Toolkit (Unity 6.3+)
|   +-- Hybride (local + cloud) -> ISaveStorage abstraction (voir `references/save-advanced.md`)
|
+-- Sensible (anti-cheat) ?
    +-- Encryption AES + hash d'integrite (voir `references/save-advanced.md`)

分步指南

步骤 1 — 选择序列化格式
标准JsonUtilityNewtonsoft.JsonMemoryPackMessagePack
设置Unity 内置Unity PackageNuGetNuGet
多态否是(TypeNameHandling)是是
Dictionary否是是是
可读性JSONJSON二进制二进制
性能快中等非常快快
大小中等中等小小
推荐用途原型开发默认推荐>10 MB 数据二进制替代方案
步骤 2 — 创建 ISaveable 和 SaveData
  • 定义 ISaveable:SaveKey、CaptureState()、RestoreState(object)
  • 创建包含 version 字段、Dictionary<string, object> 和元数据的 SaveData
  • 完整代码(ISaveable、SaveData、SaveManager)参见 references/save-templates.md
步骤 3 — 实现 SaveManager
  • 使用单例或服务定位器模式(参见 /unity 架构)
  • 注册 ISaveable(Register/Unregister)
  • SaveAsync:捕获所有状态 -> 序列化 -> 原子写入(.tmp -> .save,保留 .bak)
  • LoadAsync:读取文件 -> 反序列化 -> 恢复所有状态
  • 路径:Path.Combine(Application.persistentDataPath, "saves", slotName + ".save")
步骤 4 — 自动保存
  • Dirty flag:每个 ISaveable 在状态变化时发出通知
  • 可配置计时器(默认 60-120s)
  • 在 OnApplicationPause(true) 和场景切换时保存
  • 自动保存部分参见 references/save-advanced.md
步骤 5 — 测试保存/加载流程
  • EditMode 测试:保存 -> 清除状态 -> 加载 -> 断言状态已恢复
  • 损坏测试:加载截断的文件 -> 验证是否回退到 .bak
  • 迁移测试:使用 v2 代码加载 v1 存档

严格规则

始终
  • 始终使用原子写入(写入 .tmp、重命名、保留 .bak)
  • 始终对 SaveData 进行版本控制(每次架构变更都递增 version 字段)
  • 始终使用 Application.persistentDataPath(绝不使用 dataPath 或 streamingAssetsPath)
  • 始终在移动设备上通过 OnApplicationPause(true) 保存
  • 始终序列化 POCO(Plain Old C# Objects)——不要使用 Unity 类型
  • 始终处理“没有存档”的情况(首次启动)
绝不
  • 绝不使用 BinaryFormatter——已知存在安全漏洞,且已弃用
  • 绝不在存档中存储 MonoBehaviour、GameObject 或 ScriptableObject 引用
  • 绝不在主线程上同步保存大于 100 KB 的文件
  • 绝不在写入新文件前删除旧文件(崩溃时必然导致数据损坏)
  • 绝不忽略 I/O 异常——始终使用 try/catch 并提供回退方案

相关技能

  • /unity-code-gen — 生成 ISaveable 和 SaveManager 样板代码
  • /unity-test — 用于验证保存/加载周期的 EditMode 测试
  • /unity-debug — 诊断反序列化问题
  • /addressables — 通过地址字符串保存资源引用

故障排除

问题可能原因解决方案
加载时出现 FileNotFoundException首次启动,没有存档加载前检查 File.Exists(),并返回默认数据
更新后数据丢失Schema 变更但未迁移添加 version 字段 + v1->v2->vN 迁移链
JsonSerializationException无法识别多态类型Newtonsoft:TypeNameHandling.Auto + 自定义 SerializationBinder
存档损坏(JSON 被截断)写入期间崩溃原子写入(.tmp -> rename)+ 回退到 .bak
UnauthorizedAccessException路径未获授权(Android 作用域)仅使用 persistentDataPath
PlayerPrefs 消失(iOS)系统清理或重新安装将重要数据迁移到文件中
存档过大(>50 MB)对大量数据进行 JSON 序列化改用 MemoryPack/MessagePack,并压缩(GZip)
云端/本地不同步版本冲突实现冲突解决机制(时间戳或版本计数器)

评论

支持 Markdown