Unity JSON 数据存储与读取最佳实践:JsonMgr 工具类
Unity JSON 数据存储与读取最佳实践:JsonMgr 工具类
Unity JSON 数据存储与读取最佳实践:JsonMgr 工具类详解
在 Unity 游戏开发中,数据持久化是一个必不可少的环节。今天我要分享一个我自己封装的 JSON 数据管理工具类 JsonMgr
,它简化了 Unity 中 JSON 的序列化和反序列化过程,并支持多种 JSON 处理库。
为什么需要这个工具类?
在 Unity 开发中,我们经常需要:
- 保存游戏设置
- 存储玩家进度
- 管理游戏配置数据
虽然 Unity 提供了 JsonUtility
,但在实际使用中我发现它有一些局限性:
- 对复杂数据结构支持不够友好
- 需要处理文件路径和 IO 操作
- 不同平台路径处理差异
而第三方库如 LitJson
虽然功能强大,但 API 使用不够统一。因此我封装了这个 JsonMgr
工具类来解决这些问题。
工具类设计
核心特性
- 双 JSON 引擎支持:同时支持 Unity 原生
JsonUtility
和第三方LitJson
- 智能路径查找:自动尝试从不同路径加载数据
- 简洁 API:只需一两行代码即可完成数据存取
- 安全设计:文件不存在时返回默认值而非抛出异常
代码实现
public enum JsonType
{
JsonUnity, // Unity 原生 JsonUtility
LitJson // 第三方 LitJson
}
public class JsonMgr
{
// 单例模式确保全局唯一访问点
private static JsonMgr instance;
public static JsonMgr Instance => instance;
// 保存数据方法
public void SaveData(object obj, string fileName, JsonType jsonType = JsonType.LitJson)
{
string path = Path.Combine(Application.persistentDataPath, $"{fileName}.json");
string json = jsonType == JsonType.JsonUnity
? JsonUtility.ToJson(obj)
: LitJson.JsonMapper.ToJson(obj);
File.WriteAllText(path, json);
}
// 加载数据方法
public T LoadData<T>(string fileName, JsonType jsonType = JsonType.LitJson) where T : new()
{
// 优先尝试从 StreamingAssets 加载
string path = Path.Combine(Application.streamingAssetsPath, $"{fileName}.json");
if(!File.Exists(path))
path = Path.Combine(Application.persistentDataPath, $"{fileName}.json");
if (!File.Exists(path))
return new T();
string jsonStr = File.ReadAllText(path);
return jsonType == JsonType.JsonUnity
? JsonUtility.FromJson<T>(jsonStr)
: LitJson.JsonMapper.ToObject<T>(jsonStr);
}
}
使用示例
1. 定义数据类
[Serializable]
public class PlayerData
{
public string playerName;
public int level;
public float experience;
public List<string> inventory;
}
2. 保存数据
// 创建玩家数据
var player = new PlayerData
{
playerName = "游戏开发者",
level = 99,
experience = 9999.9f,
inventory = new List<string> { "剑", "盾", "药水" }
};
// 使用 LitJson 保存(默认)
JsonMgr.Instance.SaveData(player, "player_data");
// 使用 Unity JsonUtility 保存
JsonMgr.Instance.SaveData(player, "player_data_backup", JsonType.JsonUnity);
3. 加载数据
// 使用 LitJson 加载(默认)
PlayerData loadedData = JsonMgr.Instance.LoadData<PlayerData>("player_data");
// 使用 Unity JsonUtility 加载
PlayerData backupData = JsonMgr.Instance.LoadData<PlayerData>("player_data_backup", JsonType.JsonUnity);
技术细节解析
1. 路径处理策略
工具类采用了双路径查找策略:
- 首先检查
StreamingAssets
路径 - 适合存放初始/只读数据 - 如果不存在,再检查
PersistentDataPath
- 适合存放运行时修改的数据
这种设计既保证了初始数据的存在,又允许玩家数据被修改保存。
2. JSON 引擎选择
提供两种 JSON 处理引擎可选:
- JsonUtility:Unity 原生,性能较好,但对复杂类型支持有限
- LitJson:功能更强大,支持字典等复杂结构
3. 错误处理
当文件不存在时,LoadData
方法会返回类型 T
的新实例,而不是抛出异常。这种"宽容"设计使得调用方可以更简洁地处理默认情况。
最佳实践建议
-
数据类设计:
- 标记为
[Serializable]
- 提供无参构造函数
- 避免使用多态和复杂继承结构
- 标记为
-
文件管理:
- 初始配置放在
StreamingAssets
- 玩家数据保存在
PersistentDataPath
- 定期备份重要数据
- 初始配置放在
-
性能考虑:
- 频繁存取的数据可以考虑内存缓存
- 大数据量考虑分文件存储
-
版本兼容:
- 考虑添加数据版本字段
- 为数据结构变更准备迁移方案
扩展思考
这个工具类还可以进一步扩展:
- 添加异步保存/加载支持
- 增加加密功能保护玩家数据
- 添加压缩功能减少存储空间
- 实现数据变更自动保存
总结
JsonMgr
工具类通过简洁的 API 封装了 Unity 中 JSON 数据存取的复杂性,提供了灵活可靠的解决方案。无论是简单的玩家偏好设置,还是复杂的游戏状态保存,都能轻松应对。
在实际项目中,这个工具类已经帮我节省了大量重复工作,希望它也能为你的 Unity 开发带来便利!如果你有任何改进建议,欢迎在评论区交流讨论。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)