Unity 中使用 JSON 进行数据交互与序列化全指南**
在游戏开发中,数据的存储、读取和传递是至关重要的环节,JSON(JavaScript Object Notation)作为一种轻量级、易读、易解析的数据交换格式,在 Unity 开发中得到了广泛应用,无论是配置文件、存档数据、网络通信,还是场景数据的序列化与反序列化,JSON 都能提供简洁高效的解决方案,本文将详细介绍如何在 Unity 中使用 JSON。
什么是 JSON?
JSON 是一种基于文本的格式,它结构清晰,类似于 JavaScript 中的对象和数组,它主要由两种结构组成:
- 键值对(Key-Value Pairs):类似于字典或哈希表,键(Key)是字符串,值(Value)可以是字符串、数字、布尔值、null、数组或另一个 JSON 对象。
- 数组(Arrays):值的有序列表,值可以是字符串、数字、布尔值、null、数组或 JSON 对象。
一个简单的 JSON 对象可能如下:
{
"playerName": "Alice",
"playerLevel": 10,
"health": 100.5,
"isAlive": true,
"inventory": ["Sword", "Shield", "Potion"],
"position": {
"x": 1.0,
"y": 2.0,
"z": 3.0
}
}
Unity 中使用 JSON 的几种方式
Unity 本身没有提供原生的、专门针对 JSON 的序列化类(如 System.Text.Json.JsonSerializer 或 Newtonsoft.Json.JsonConvert 这些在 .NET 标准库中常见的),但我们可以通过以下几种方式实现 JSON 的操作:
使用 Unity 的 JsonUtility(内置推荐)
Unity 提供了 JsonUtility 类,它是 Unity 内置的 JSON 序列化工具,专门为 Unity 的对象模型设计,使用简单,性能较好,尤其适合序列化 Unity 的 ScriptableObject 和普通的 C# 类。
优点:
- 内置,无需额外插件。
- 与 Unity 引擎集成度高,支持序列化
Vector2,Vector3,Quaternion等 Unity 类型。 - 性能较好。
缺点:
- 功能相对简单,不支持某些复杂的 JSON 特性(如多态、字典的直接序列化 - 需要额外处理)。
- 要求序列化的类必须是可序列化的(有
[Serializable]特性),并且字段必须是public或有[SerializeField]特性。
使用示例:
a. 定义可序列化的 C# 类:
using UnityEngine;
using System.Collections.Generic;
[System.Serializable]
public class PlayerData
{
public string playerName;
public int playerLevel;
public float health;
public bool isAlive;
public List<string> inventory;
public Vector3 position; // JsonUtility 支持 Vector3 等 Unity 类型
// 可以添加构造函数方便初始化
public PlayerData(string name, int level, float hp, bool alive, List<string> inv, Vector3 pos)
{
playerName = name;
playerLevel = level;
health = hp;
isAlive = alive;
inventory = inv;
position = pos;
}
}
b. 序列化(对象转 JSON 字符串):
using UnityEngine;
public class JsonSerializationExample : MonoBehaviour
{
void Start()
{
PlayerData playerData = new PlayerData("Bob", 5, 80.0f, true, new List<string> {"Bow", "Arrows"}, new Vector3(0, 0, 0));
// 将对象序列化为 JSON 字符串
string json = JsonUtility.ToJson(playerData);
Debug.Log("Serialized JSON: " + json);
// 如果想要美化输出(格式化),可以传入 prettyPrint 参数
string prettyJson = JsonUtility.ToJson(playerData, true);
Debug.Log("Pretty JSON: " + prettyJson);
}
}
c. 反序列化(JSON 字符串转对象):
using UnityEngine;
public class JsonDeserializationExample : MonoBehaviour
{
void Start()
{
string json = "{\"playerName\":\"Charlie\",\"playerLevel\":15,\"health\":120.5,\"isAlive\":true,\"inventory\":[\"Staff\",\"Orb\"],\"position\":{\"x\":5.0,\"y\":3.0,\"z\":-2.0}}";
// 将 JSON 字符串反序列化为对象
PlayerData playerData = JsonUtility.FromJson<PlayerData>(json);
Debug.Log("Deserialized Player Name: " + playerData.playerName);
Debug.Log("Deserialized Player Level: " + playerData.playerLevel);
Debug.Log("Deserialized Inventory: " + string.Join(", ", playerData.inventory));
}
}
d. 处理 List 和数组:
JsonUtility 可以直接处理 List<T> 和数组,反序列化时,JSON 中是数组,目标字段可以是 List<T> 或 T[]。
e. 处理字典(Dictionary):
JsonUtility 不能直接序列化 Dictionary<K, V>,一种常见的 workaround 是创建一个包含键值对列表的包装类。
[System.Serializable]
public class SerializableDictionary<TKey, TValue>
{
public List<TKey> keys = new List<TKey>();
public List<TValue> values = new List<TValue>();
// 可以添加方法来模拟字典行为
public void Add(TKey key, TValue value)
{
keys.Add(key);
values.Add(value);
}
// 其他字典方法...
}
// 然后在你的主类中使用这个包装类
[System.Serializable]
public class PlayerStats
{
public SerializableDictionary<string, int> statModifiers = new SerializableDictionary<string, int>();
}
使用第三方库(如 LitJson, Newtonsoft.Json)
当 JsonUtility 无法满足需求(例如需要更复杂的 JSON 结构、更好的性能、支持多态、更完善的错误处理等)时,可以使用第三方 JSON 库。
常用库:
- LitJson:轻量级,易于使用,在 Unity 社区中很流行。
- Newtonsoft.Json (Json.NET):功能非常强大,是 .NET 生态中最流行的 JSON 库,但体积相对较大,需要额外导入。
以 LitJson 为例(需要先从 Unity Asset Store 或 GitHub 导入):
a. 安装 LitJson:
- 从 Unity Asset Store 下载 "LitJson" 并导入。
- 或者从 GitHub 下载源码,将
LitJson文件夹放入 Unity 的Assets/Plugins或Assets/Scripts目录下。
b. 使用示例:
序列化:
using LitJson;
using UnityEngine;
public class LitJsonSerializationExample : MonoBehaviour
{
void Start()
{
PlayerData playerData = new PlayerData("Diana", 12, 95.0f, true, new List<string> {"Armor", "Helmet"}, new Vector3(10, 5, -1));
// 使用 JsonMapper 将对象序列化为 JSON 字符串
string json = JsonMapper.ToJson(playerData);
Debug.Log("LitJSON Serialized: " + json);
}
}
反序列化:
using LitJson;
using UnityEngine;
public class LitJsonDeserializationExample : MonoBehaviour
{
void Start()
{
string json = "{\"playerName\":\"Eve\",\"playerLevel\":20,\"health\":150.0,\"isAlive\":true,\"inventory\":[\"Axe\",\"Pickaxe\"],\"position\":{\"x\":-3.0,\"y\":7.0,\"z\":2.0}}";
// 使用 JsonMapper 将 JSON 字符串反序列化为对象
PlayerData playerData = JsonMapper.ToObject<PlayerData>(json);
Debug.Log("LitJSON Deserialized Player Name: " + playerData.playerName);
Debug.Log("LitJSON Deserialized Player Level: " + playerData.playerLevel);
}
}
LitJson 对字典的支持比 JsonUtility 好得多,可以直接处理 Dictionary<string, object> 等类型。
手动解析 JSON(不推荐用于复杂场景)
对于非常简单的 JSON 结构,或者在没有外部库且 JsonUtility 不适用的情况下,可以手动解析 JSON 字符串,但这通常涉及大量的字符串操作,容易出错,且难以维护,只适用于极简单的场景。
Unity 中 JSON 的常见应用场景
- 游戏配置文件:将游戏中的参数、敌人属性、物品信息等存储为 JSON 文件,方便策划和美术调整,无需重新编译代码。
enemyConfig.json,itemDatabase.json。
- 存档/读档:将玩家的游戏进度(角色信息、背包、任务状态等)序列化为 JSON 字符串并保存到文件,读取时再反序列化。
- 网络通信:客户端与服务器之间通常使用 JSON 格式传输数据,因为其轻量且



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