Unity 读取 JSON 文件完全指南:从基础到实践**
在游戏开发中,数据存储与读取是至关重要的环节,JSON(JavaScript Object Notation)以其轻量级、易读易写、易于解析以及与语言无关的特性,成为了Unity项目中存储配置数据、关卡信息、角色属性等的首选格式之一,本文将详细介绍在Unity中读取JSON文件的多种方法,从简单的TextAsset直接读取到使用强大的JsonUtility和第三方库Newtonsoft.Json,并提供完整的代码示例和最佳实践。
准备工作:创建JSON文件
我们需要在Unity项目中创建一个JSON文件,推荐将JSON文件放置在项目的Resources文件夹下,这样可以通过Resources.Load方法直接加载,无需关心文件的完整路径。
- 在Unity编辑器中,右键点击
Assets窗口,选择Create > Folder,命名为Resources。 - 右键点击
Resources文件夹,选择Create > Text Asset,命名为data.json(或其他你喜欢的名字)。 - 双击打开
data.json文件,输入一些JSON格式的数据,我们定义一个简单的玩家数据对象:
{
"playerName": "Alice",
"playerLevel": 10,
"playerHealth": 100,
"playerPosition": {
"x": 1.5,
"y": 2.3,
"z": 0.0
},
"inventory": [
"sword",
"shield",
"potion"
]
}
注意: JSON文件中的键(key)必须使用双引号包围。
方法一:使用 Resources.Load 和 TextAsset(简单直接)
对于简单的JSON数据,我们可以直接将其作为TextAsset加载,然后将其内容作为字符串读取。
步骤:
- 确保JSON文件位于
Resources文件夹。 - 编写C#脚本进行读取。
示例代码:
using UnityEngine;
public class JsonReaderExample : MonoBehaviour
{
void Start()
{
// 1. 加载Resources文件夹下的JSON文件(不包含扩展名)
TextAsset jsonFile = Resources.Load<TextAsset>("data");
if (jsonFile != null)
{
// 2. 获取JSON文本内容
string jsonString = jsonFile.text;
Debug.Log("成功读取JSON文件内容:");
Debug.Log(jsonString);
// 注意:此时jsonString只是一个字符串,需要进一步解析为对象
// 解析方法将在后续介绍(如JsonUtility或Newtonsoft.Json)
}
else
{
Debug.LogError("未找到指定的JSON文件!请确保文件位于Resources文件夹下且名称正确。");
}
}
}
优点:
- 简单易用,无需额外库。
Resources文件夹下的文件在打包时会包含在最终游戏中。
缺点:
- 仅适用于
Resources文件夹。 - 加载后得到的是字符串,需要手动解析为对象。
方法二:使用 JsonUtility(Unity官方推荐)
JsonUtility是Unity提供的用于序列化和反序列化JSON数据的官方类,性能较好,与Unity的ScriptableObject集成良好,但它有一些限制,例如不能直接处理字典(Dictionary)和某些复杂集合。
前提: 需要一个C#类来映射JSON的结构,类的字段名必须与JSON的键名完全一致(不区分大小写,但最佳实践是保持一致)。
示例代码(基于前面的data.json):
using UnityEngine;
using System.Collections.Generic;
// 1. 定义与JSON结构对应的C#类
[System.Serializable] // 必须可序列化
public class PlayerData
{
public string playerName;
public int playerLevel;
public float playerHealth;
public PlayerPosition playerPosition; // 嵌套对象
public List<string> inventory; // 数组/列表
}
[System.Serializable]
public class PlayerPosition
{
public float x;
public float y;
public float z;
}
public class JsonUtilityExample : MonoBehaviour
{
void Start()
{
TextAsset jsonFile = Resources.Load<TextAsset>("data");
if (jsonFile != null)
{
string jsonString = jsonFile.text;
// 2. 使用JsonUtility.FromJson将JSON字符串反序列化为对象
PlayerData playerData = JsonUtility.FromJson<PlayerData>(jsonString);
// 3. 访问数据
Debug.Log("玩家姓名: " + playerData.playerName);
Debug.Log("玩家等级: " + playerData.playerLevel);
Debug.Log("玩家生命值: " + playerData.playerHealth);
Debug.Log("玩家位置: X=" + playerData.playerPosition.x +
", Y=" + playerData.playerPosition.y +
", Z=" + playerData.playerPosition.z);
Debug.Log("背包物品: ");
foreach (var item in playerData.inventory)
{
Debug.Log("- " + item);
}
}
else
{
Debug.LogError("未找到JSON文件!");
}
}
}
JsonUtility的注意事项:
- [System.Serializable]:类必须标记为可序列化。
- 字段名匹配:C#类字段名需与JSON键名匹配。
- 复杂类型:对字典(Dictionary)的支持有限,需要一些技巧或转换,可以将字典的键值对列表表示为
List<KeyValuePair<K, V>>,然后手动转换。 - JSON根对象:JsonUtility通常处理单个根对象,如果JSON是数组,可以将其包装在一个对象中,或者使用
List<T>配合JsonUtility.FromJsonOverlaps(较复杂,推荐使用第三方库处理数组)。
方法三:使用第三方库(如 Newtonsoft.Json / Json.NET)
当JsonUtility无法满足需求时(例如处理复杂JSON、字典、数组、自定义转换器等),Newtonsoft.Json(也称为Json.NET)是一个非常强大和流行的选择。
步骤:
-
导入库:
- 最简单的方式是通过Unity Package Manager(UPM)安装,在Window > Package Manager中,点击“+”号,选择“Add package from git URL...”,输入
com.unity.newtonsoft-json(如果官方包已发布)或从其他来源获取。 - 或者直接下载Newtonsoft.Json的.dll文件,将其放在Unity项目的
Assets/Plugins或Assets/Plugins/Editor文件夹下。
- 最简单的方式是通过Unity Package Manager(UPM)安装,在Window > Package Manager中,点击“+”号,选择“Add package from git URL...”,输入
-
编写代码:
示例代码(使用Newtonsoft.Json读取相同的data.json):
using UnityEngine;
using Newtonsoft.Json; // 需要导入Newtonsoft.Json命名空间
// PlayerData和PlayerPosition类定义与JsonUtility示例中相同,无需[Serializable]
public class PlayerDataNewtonsoft
{
public string playerName;
public int playerLevel;
public float playerHealth;
public PlayerPosition playerPosition;
public List<string> inventory;
}
public class NewtonsoftJsonExample : MonoBehaviour
{
void Start()
{
TextAsset jsonFile = Resources.Load<TextAsset>("data");
if (jsonFile != null)
{
string jsonString = jsonFile.text;
// 使用JsonConvert.DeserializeObject反序列化
PlayerDataNewtonsoft playerData = JsonConvert.DeserializeObject<PlayerDataNewtonsoft>(jsonString);
// 访问数据(与JsonUtility示例类似)
Debug.Log("玩家姓名 (Newtonsoft): " + playerData.playerName);
Debug.Log("玩家等级 (Newtonsoft): " + playerData.playerLevel);
// ... 其他数据访问
}
else
{
Debug.LogError("未找到JSON文件!");
}
}
}
Newtonsoft.Json的优点:
- 功能强大,支持复杂的JSON结构。
- 良好的错误处理和诊断信息。
- 支持自定义序列化器和反序列化器。
- 对LINQ to JSON的支持,方便动态查询和操作JSON。
Newtonsoft.Json的缺点:
- 需要额外引入库,增加项目体积(尽管通常不大)。
- 对于非常简单的JSON,可能显得有些“重”。
从StreamingAssets文件夹读取(适用于移动平台)
有时,JSON文件可能需要从StreamingAssets文件夹读取(用户生成的JSON文件或需要更新的配置文件)。StreamingAssets文件夹中的文件在构建后会保持原样,可以通过特定的URL路径访问。
示例代码:
using UnityEngine;
using System.IO;
using System.Collections; // 用于协程
public class StreamingAssetsJsonReader : MonoBehaviour
{
void Start()
{
// StartCoroutine(ReadJsonFromStreamingAssets());
ReadJsonFromStreamingAssetsSync(); // 同步方法(可能阻塞主线程,不推荐)
}
// 异步读取(推荐)
IEnumerator ReadJsonFromStreamingAssets()
{
string filePath = Path.Combine(Application.streamingAssetsPath, "data.json");
string jsonString = "";
#if UNITY_ANDROID && !UNITY_EDITOR
// Android平台需要使用WWW或UnityWebRequest读取
using (WWW www = new WWW(filePath))
{
yield return www;
if (string.IsNullOrEmpty


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