当前位置: 首页 > news >正文

Unity_数据持久化_Json

Unity_数据持久化

四、Json数据持久化

4.1 Json基本语法

4.1.1 基本概念

什么是JSON:
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下特点:

  • 轻量级:相比XML,JSON格式更简洁,数据量更小
  • 可读性:人类和机器都能轻松理解
  • 跨平台:不依赖特定编程语言,支持多种平台
  • 自描述性:数据结构清晰,易于解析

JSON在Unity中的应用:

  • 游戏配置数据存储
  • 网络通信数据格式
  • 存档文件格式
  • 第三方API数据交换
4.1.2 数据类型

JSON支持六种基本数据类型:

1. 字符串(String)

"Hello World"
"Unity游戏开发"
"12345"

2. 数字(Number)

42          // 整数
3.14        // 浮点数
-273        // 负数
1.23e-4     // 科学计数法

3. 布尔值(Boolean)

true        // 真
false       // 假

4. 空值(Null)

null        // 表示空值或未定义

5. 数组(Array)

[1, 2, 3, 4, 5]                    // 数字数组
["苹果", "香蕉", "橙子"]            // 字符串数组
[true, false, true]                 // 布尔值数组
[1, "混合", true, null]            // 混合类型数组

6. 对象(Object)

{"name": "张三","age": 25,"isStudent": true
}
4.1.3 语法规则

基本语法规则:

1. 键值对格式

{"键名": "值"
}

2. 命名规则

  • 键名必须用双引号包围
  • 键名区分大小写
  • 键名不能重复
  • 支持中文和特殊字符

3. 值类型规则

  • 字符串必须用双引号包围
  • 数字不需要引号
  • 布尔值和null不需要引号
  • 数组和对象不需要引号

4. 嵌套规则

{"player": {"name": "张三","stats": {"health": 100,"mana": 50},"inventory": [{"id": 1, "name": "剑"},{"id": 2, "name": "盾"}]}
}

5. 分隔符规则

  • 键值对之间用逗号分隔
  • 数组元素之间用逗号分隔
  • 最后一个元素后不能有逗号
4.1.4 格式示例

游戏数据JSON示例:

1. 玩家信息

{"playerId": 1001,"playerName": "游戏玩家","level": 15,"experience": 2500,"isOnline": true,"lastLogin": "2024-01-15T10:30:00Z","position": {"x": 100.5,"y": 200.0,"z": 50.0},"skills": ["剑术", "魔法", "治疗"],"equipment": {"weapon": "传说之剑","armor": "龙鳞甲","accessory": "生命戒指"}
}

2. 游戏配置

{"gameSettings": {"graphics": {"resolution": "1920x1080","quality": "high","fullscreen": false},"audio": {"masterVolume": 0.8,"musicVolume": 0.6,"sfxVolume": 0.9},"controls": {"mouseSensitivity": 1.0,"invertY": false,"keyBindings": {"moveForward": "W","moveBackward": "S","moveLeft": "A","moveRight": "D"}}}
}

4.3 C#读取存储Json文件

4.3.1 JsonUtility
4.3.1.1 基本概念

什么是JsonUtility:
JsonUtility是Unity内置的JSON序列化工具,提供了线程安全的方法,可以将C#类对象序列化为JSON字符串,也可以将JSON字符串反序列化为C#对象。

核心特点:

  • 内置工具:Unity引擎自带,无需额外导入
  • 线程安全:提供线程安全的序列化方法
  • 简单易用:API简洁,学习成本低
  • 性能优化:针对Unity引擎优化
4.3.1.2 主要方法

核心序列化方法:

// 序列化:将对象转换为JSON字符串
string jsonString = JsonUtility.ToJson(object obj);
string jsonString = JsonUtility.ToJson(object obj, bool prettyPrint);// 反序列化:将JSON字符串转换为对象
T result = JsonUtility.FromJson<T>(string json);

参数说明:

  • obj:要序列化的对象
  • prettyPrint:是否格式化输出(美化JSON格式)
  • T:目标类型
  • json:JSON字符串
4.3.1.3 使用示例

基于您的脚本的完整示例:

using UnityEngine;
using System.IO;
using System.Collections.Generic;[System.Serializable]
public class Skill
{public int id;public string name;public int damage;// 必须有无参构造函数public Skill() { }public Skill(int id, string name, int damage){this.id = id;this.name = name;this.damage = damage;}
}[System.Serializable]
public class Player
{public int id;public string name;public List<int> nums;public Skill skill;public List<Skill> skills;// 注意:Dictionary类型JsonUtility不支持// public Dictionary<string,int> dict;// public Dictionary<string,Skill> dict2;
}public class JsonUtilityExample : MonoBehaviour
{void Start(){// 创建测试数据Player player = new Player();player.id = 1;player.name = "张三";player.nums = new List<int>(){1, 2, 3};player.skill = new Skill(1, "技能1", 100);player.skills = new List<Skill>(){new Skill(2, "技能2", 200), new Skill(3, "技能3", 300)};// 序列化对象为JSON字符串string jsonString = JsonUtility.ToJson(player, true); // 美化输出print("序列化结果: " + jsonString);// 保存到文件string filePath = Application.persistentDataPath + "/player.json";File.WriteAllText(filePath, jsonString);print("文件保存路径: " + filePath);// 从文件读取JSON字符串string loadedJson = File.ReadAllText(filePath);// 反序列化JSON字符串为对象Player player2 = JsonUtility.FromJson<Player>(loadedJson);// 验证反序列化结果if (player2 != null){print("反序列化成功!");print("玩家ID: " + player2.id);print("玩家姓名: " + player2.name);print("数字列表第一个: " + player2.nums[0]);print("技能名称: " + player2.skill.name);print("技能列表第一个: " + player2.skills[0].name);}}
}
4.3.1.4 优缺点分析

优点:

  • 内置工具:无需额外导入第三方库
  • 性能优秀:针对Unity引擎优化
  • 简单易用:API简洁明了
  • 线程安全:提供线程安全的序列化方法

缺点:

  • 功能限制:不支持Dictionary等复杂类型
  • 特性要求:需要添加[System.Serializable]特性
  • 私有字段:默认不支持私有字段序列化
  • 精度问题:float类型可能有精度误差
4.3.1.5 注意事项

重要限制和注意事项:

1. 序列化特性要求

// 自定义类必须添加[System.Serializable]特性
[System.Serializable]
public class CustomClass
{public string name;public int value;
}

2. 私有字段序列化

[System.Serializable]
public class CustomClass
{public string publicField;        // 可以直接序列化[SerializeField]                  // 需要添加此特性private string privateField;      // 私有字段才能序列化
}

3. 不支持的数据类型

// JsonUtility不支持以下类型:
// - Dictionary<TKey, TValue>
// - 接口类型
// - 委托类型
// - 静态字段
// - 只读字段

4. 构造函数要求

public class Skill
{public int id;public string name;// 必须有无参构造函数public Skill() { }public Skill(int id, string name){this.id = id;this.name = name;}
}

5. 精度问题

// float类型在序列化时可能有精度误差
public float preciseValue = 3.14159f;
// 序列化后可能变成3.14159或3.1416
4.3.2 LitJson
4.3.2.1 基本概念

什么是LitJson:
LitJson是一个第三方库,用于处理Json的序列化和反序列化。它是C#编写的,体积小、速度快、易于使用,可以很容易地嵌入到我们的代码中。

核心特点:

  • 第三方库:不属于Unity官方内置工具
  • C#编写:完全由C#语言实现
  • 体积小:代码库占用空间小
  • 速度快:序列化和反序列化性能优秀
  • 易于使用:API设计简洁直观
  • 易于嵌入:只需要将LitJson代码拷贝到工程中即可
4.3.2.2 获取LitJson

获取方式:

  1. 前往LitJson官网
  2. 通过官网前往GitHub获取最新版本代码
  3. 将代码拷贝到Unity工程中即可开始使用LitJson
4.3.2.3 使用LitJson进行序列化

方法:

JsonMapper.ToJson(对象)

注意:

  1. 相对JsonUtility不需要加特性
  2. 不能序列化私有变量
  3. 支持字典类型
  4. 需要引用LitJson命名空间
4.3.2.4 使用LitJson反序列化

方法:

JsonMapper.ToObject<类型>(json字符串)

两种反序列化方式:

1. 动态反序列化(使用JsonData)

// JsonData是LitJson提供的类对象,可以用键值对的形式去访问其中的内容
JsonData data = JsonMapper.ToObject(jsonStr);
print(data["name"]);
print(data["age"]);

2. 强类型反序列化(使用泛型)

// 通过泛型转换更加的方便,建议使用这种方式
MrTang2 t2 = JsonMapper.ToObject<MrTang2>(jsonStr);

注意:

  1. 类结构需要无参构造函数,否则反序列化时报错
  2. 字典虽然支持,但是键在使用为数值时会有问题,需要使用字符串类型
  3. 需要引用LitJson命名空间
4.3.2.5 优缺点分析

优点:

  • 支持Dictionary:原生支持Dictionary等复杂类型
  • 体积小:代码库占用空间小
  • 速度快:序列化和反序列化性能优秀
  • 易于使用:API简洁,学习成本低
  • 易于嵌入:只需拷贝文件即可使用

缺点:

  • 第三方库:不属于Unity官方工具
  • 功能相对简单:相比大型JSON库功能有限
  • 更新维护:依赖第三方维护更新
  • 错误处理:错误信息可能不够详细
4.3.3 JsonUtility和LitJson对比
4.3.3.1 相似点

共同特点:

  • 都是用于JSON序列化和反序列化
  • JSON文档编码格式必须是UTF-8
  • 都是通过静态类调用方法
4.3.3.2 差异点

主要区别:

1. 来源和导入

  • JsonUtility:Unity内置,无需额外导入
  • LitJson:第三方库,需要导入命名空间

2. 特性要求

  • JsonUtility:自定义类使用时需要加特性
  • LitJson:不需要加特性

3. 私有变量支持

  • JsonUtility:支持私有变量(需要加特性)
  • LitJson:不支持私有变量

4. 字典类型支持

  • JsonUtility:不支持字典
  • LitJson:支持字典(但键必须是字符串)

5. 数据集合反序列化

  • JsonUtility:不能直接反序列化数据到数据集合(如数组字典)
  • LitJson:可以

6. 构造函数要求

  • JsonUtility:自定义类不需要有无参构造函数
  • LitJson:需要有无参构造函数

7. null值处理

  • JsonUtility:存储null对象时不会是null,而是默认值的数据
  • LitJson:存储null
4.3.3.3 选择方法

选择标准:

  • 根据项目需求选择合适的工具
  • 考虑性能、功能、维护成本等因素
  • 权衡内置工具和第三方库的优缺点
4.3.3.4 选择建议

推荐使用场景:

选择JsonUtility的情况:

  • 项目对性能要求较高
  • 数据结构相对简单
  • 希望使用Unity官方工具
  • 不需要支持Dictionary类型

选择LitJson的情况:

  • 需要支持Dictionary等复杂类型
  • 对序列化特性没有严格要求
  • 希望更灵活的JSON处理能力
  • 可以接受第三方库的维护成本
http://www.lryc.cn/news/621768.html

相关文章:

  • Ubuntu DNS 综合配置与排查指南
  • 小程序上拉加载下一页数据
  • 基于HTML5与Tailwind CSS的现代运势抽签系统技术解析
  • GEO入门:什么是生成式引擎优化?它与SEO的根本区别在哪里?
  • 流处理、实时分析与RAG驱动的Python ETL框架:构建智能数据管道(中)
  • Fanuc机器人EtherCAT通讯配置详解
  • 【Linux基础知识系列】第九十六篇 - 使用history命令管理命令历史
  • 【机器人】人形机器人“百机大战”:2025年产业革命的烽火与技术前沿
  • Zabbix【部署 01】Zabbix企业级分布式监控系统部署配置使用实例(在线安装及问题处理)程序安装+数据库初始+前端配置+服务启动+Web登录
  • 在 Vue2 中使用 pdf.js + pdf-lib 实现 PDF 预览、手写签名、文字批注与高保真导出
  • 力扣习题:基本计算器
  • Spring 工具类:StopWatch
  • Java 泛型类型擦除
  • 【递归、搜索与回溯算法】DFS解决FloodFill算法
  • Pytest项目_day17(随机测试数据)
  • JUC学习笔记-----LongAdder
  • 2025年最新油管视频下载,附MassTube下载软件地址
  • 嵌入式 C 语言编程规范个人学习笔记,参考华为《C 语言编程规范》
  • 嵌入式硬件篇---电容串并联
  • 嵌入式硬件篇---电容滤波
  • flutter开发(二)检测媒体中的静音
  • Flinksql bug: Heartbeat of TaskManager with id container_XXX timed out.
  • 对抗损失(GAN)【生成器+判断器】
  • LeetCode 922.按奇偶排序数组2
  • 大模型LLM部署与入门应用指南:核心原理、实战案例及私有化部署
  • 解决安装特定版本 anaconda-client 的错误
  • CSS从入门到精通完整指南
  • 【科研绘图系列】R语言绘制三维曲线图
  • 探索无人机图传技术:创新视野与无限可能
  • Salary Queries