Unity中使用JSON的完整指南:从基础到实战
在Unity开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其可读性强、解析效率高,被广泛应用于数据存储、网络通信、配置文件加载等场景,无论是保存玩家数据、加载关卡配置,还是与服务器交互,JSON都是开发者的得力工具,本文将详细介绍Unity中使用JSON的多种方法,从内置的JsonUtility到第三方库Newtonsoft.Json,并结合实际场景代码,帮助你快速JSON的使用技巧。
JSON基础:什么是JSON?
JSON是一种基于文本的数据格式,采用键值对(Key-Value)的方式组织数据,结构清晰,易于人类阅读和机器解析,其基本语法包括:
- 键值对:
"key": value,键必须是字符串(用双引号包裹),值可以是字符串、数字、布尔值、数组、对象或null。 - 对象:用包裹,多个键值对之间用逗号分隔,如
{"name": "Alice", "age": 25}。 - 数组:用
[]包裹,多个值之间用逗号分隔,如[1, 2, 3]或[{"name": "Bob"}, {"name": "Charlie"}]。
在Unity中,JSON常用于以下场景:
- 保存玩家数据(如角色位置、背包物品、等级进度)。
- 加载外部配置文件(如UI文本、敌人属性、关卡参数)。
- 网络请求中传输数据(如登录接口的用户信息、排行榜数据)。
Unity内置JSON工具:JsonUtility
Unity提供了JsonUtility类(位于UnityEngine.Serialization命名空间),无需额外导入库即可实现JSON的序列化(将对象转为JSON字符串)和反序列化(将JSON字符串转为对象),这是Unity官方推荐的JSON处理方式,尤其适合处理简单的数据结构。
序列化:将对象转为JSON字符串
假设我们有一个玩家数据类PlayerData,需要将其保存为JSON格式:
using UnityEngine;
// 定义可序列化的数据类(必须标记为[Serializable])
[System.Serializable]
public class PlayerData
{
public string playerName;
public int level;
public float health;
public string[] inventory; // 数组支持
public Vector3 position; // Unity内置类型(需特殊处理)
}
public class JsonSerializationExample : MonoBehaviour
{
void Start()
{
// 创建PlayerData对象
PlayerData player = new PlayerData
{
playerName = "Hero",
level = 10,
health = 85.5f,
inventory = new string[] {"Sword", "Shield", "Potion"},
position = new Vector3(10.2f, 0f, 5.8f)
};
// 序列化为JSON字符串
string json = JsonUtility.ToJson(player, prettyPrint: true);
Debug.Log("序列化后的JSON:\n" + json);
// 可选:将JSON保存到文件(示例保存到PersistentDataPath)
string filePath = Application.persistentDataPath + "/playerData.json";
System.IO.File.WriteAllText(filePath, json);
Debug.Log("数据已保存至:" + filePath);
}
}
输出结果:
{
"playerName": "Hero",
"level": 10,
"health": 85.5,
"inventory": [
"Sword",
"Shield",
"Potion"
],
"position": {
"x": 10.2,
"y": 0.0,
"y": 5.8
}
}
注意事项:
- 类必须添加
[System.Serializable]标记,否则JsonUtility无法序列化其字段。 prettyPrint: true可使JSON格式化(缩进美化),默认为false(紧凑格式)。- Unity内置类型(如
Vector3、Quaternion、Color)会被自动拆解为基础字段(如position.x、position.y)。
反序列化:将JSON字符串转为对象
从文件或网络读取JSON字符串后,可以将其还原为对象:
using UnityEngine;
public class JsonDeserializationExample : MonoBehaviour
{
void Start()
{
// 从文件读取JSON(假设已存在playerData.json)
string filePath = Application.persistentDataPath + "/playerData.json";
if (System.IO.File.Exists(filePath))
{
string json = System.IO.File.ReadAllText(filePath);
Debug.Log("读取到的JSON:\n" + json);
// 反序列化为PlayerData对象
PlayerData player = JsonUtility.FromJson<PlayerData>(json);
// 输出数据验证
Debug.Log($"玩家名:{player.playerName}, 等级:{player.level}");
Debug.Log("位置:" + player.position);
}
else
{
Debug.LogError("未找到玩家数据文件!");
}
}
}
注意事项:
- 反序列化时,JSON的字段名必须与类的字段名完全匹配(区分大小写)。
- 如果JSON中包含类中不存在的字段,该字段会被忽略;如果类中存在JSON中不存在的字段,该字段值会被设为默认值(如
int为0,string为null)。
处理JSON数组与列表
JsonUtility直接支持数组的序列化/反序列化,但如果需要使用List<T>,需要额外处理:
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PlayerData
{
public string playerName;
public List<string> inventory; // 改用List
}
public class JsonListExample : MonoBehaviour
{
void Start()
{
// 创建包含List的对象
PlayerData player = new PlayerData
{
playerName = "Mage",
inventory = new List<string> {"Staff", "Spellbook", "Mana Potion"}
};
// 序列化时,List会被转为JSON数组
string json = JsonUtility.ToJson(player, true);
Debug.Log("序列化List的JSON:\n" + json);
// 反序列化时,JSON数组会被转为List
PlayerData deserializedPlayer = JsonUtility.FromJson<PlayerData>(json);
Debug.Log("List长度:" + deserializedPlayer.inventory.Count);
}
}
输出结果:
{
"playerName": "Mage",
"inventory": [
"Staff",
"Spellbook",
"Mana Potion"
]
}
JsonUtility的局限性
JsonUtility虽然方便,但存在以下局限:
- 不支持字典(Dictionary):直接序列化
Dictionary会报错,需通过自定义转换或改用其他库。 - 不支持循环引用:如果对象之间存在循环引用(如A包含B,B包含A),序列化会抛出异常。
- JSON格式严格:要求JSON必须是一个对象(以开头),不能是裸数组或基本类型(如字符串、数字)。
第三方JSON库:Newtonsoft.Json(Json.NET)
如果JsonUtility无法满足需求(如处理字典、复杂嵌套结构或需要更灵活的JSON操作),可以使用第三方库Newtonsoft.Json(又称Json.NET),这是.NET生态中最流行的JSON库,功能强大,支持高阶特性。
导入Newtonsoft.Json
在Unity中使用Newtonsoft.Json,需通过以下方式导入:
- Unity Package Manager:在
Window > Package Manager中点击号,选择Add package from git URL,输入com.unity.newtonsoft-json,点击安装。 - 手动导入:从Newtonsoft.Json官网下载最新版DLL文件,将
Newtonsoft.Json.dll放入Unity项目的Assets/Plugins文件夹下。
序列化与反序列化
以PlayerData为例,使用Newtonsoft.Json的代码如下:
using Newtonsoft.Json;
using UnityEngine;
public class NewtonsoftJsonExample : MonoBehaviour
{
void Start()
{
// 创建对象
PlayerData player = new PlayerData
{
playerName = "Warrior",
level = 15,
health = 120f,
inventory = new string[] {"Axe", "Armor"},
position = new Vector3(20.5f, 0f, 15.3f)
};
// 序列化(支持格式化、日期处理等)
string json = JsonConvert.SerializeObject(player, Formatting.Indented);
Debug.Log("Newtonsoft序列化结果:\n" + json);
// 反序列化
PlayerData deserializedPlayer = JsonConvert.DeserializeObject<PlayerData>(json);
Debug.Log($"反序列化玩家名:{deserializedPlayer.playerName}");
}
}
输出结果(与JsonUtility类似,但功能更灵活)。
处理字典(Dictionary)
Newtonsoft.Json原生支持字典,无需额外处理:



还没有评论,来说两句吧...