Unity中如何使用UnityJSON保存数据:完整指南
在Unity游戏开发中,数据的持久化存储是核心需求之一,无论是保存玩家的游戏进度、角色属性,还是配置文件、场景数据,都需要高效、便捷的序列化与反序列化方案,UnityJSON(即Unity自带的JsonUtility工具)是轻量级、易用的JSON处理工具,本文将详细介绍如何使用UnityJSON实现数据保存,从基础操作到进阶技巧,助你数据持久化的核心方法。
UnityJSON简介:为什么选择它?
UnityJSON是Unity引擎内置的JSON处理工具,位于UnityEngine.Serialization命名空间下,核心类是JsonUtility,与第三方JSON库(如Newtonsoft.Json、LitJSON)相比,UnityJSON的优势在于:
- 原生集成:无需额外导入插件,开箱即用,减少项目依赖;
- 性能优化:针对Unity引擎优化,序列化/反序列化速度较快;
- 无缝支持:可直接与Unity的
ScriptableObject、MonoBehaviour等组件配合,方便管理复杂数据结构; - 简单易用:API设计直观,几行代码即可完成数据转换。
UnityJSON也有局限性:不支持Dictionary类型(需转换为List< KeyValuePair<K,V>>)、对复杂嵌套结构的处理稍显繁琐,但对于大多数游戏数据存储需求,已完全够用。
数据保存的完整流程:从定义类到写入文件
使用UnityJSON保存数据,核心流程分为三步:定义可序列化的数据类 → 将对象序列化为JSON字符串 → 将JSON字符串写入持久化存储路径,下面通过具体案例拆解每一步操作。
步骤1:定义可序列化的数据类
UnityJSON只能序列化公共字段或标记为[SerializeField]的私有字段,且字段类型必须是基础类型(int、float、string、bool)或可序列化的复杂类型(如自定义类、数组、List、ScriptableObject等)。
假设我们要保存玩家的游戏数据(包括玩家名、等级、血量、背包物品列表),先定义对应的数据类:
using System.Collections.Generic;
using UnityEngine;
// 玩家数据类(需标记为[Serializable]才能被序列化)
[System.Serializable]
public class PlayerData
{
public string playerName; // 玩家名
public int level; // 等级
public float health; // 血量
public List<string> inventory; // 背包物品列表(List<string>可被序列化)
}
步骤2:将对象序列化为JSON字符串
定义好数据类后,创建对象并赋值,再通过JsonUtility.ToJson()方法将对象转换为JSON字符串。
PlayerData playerData = new PlayerData();
playerData.playerName = "Alice";
playerData.level = 10;
playerData.health = 85.5f;
playerData.inventory = new List<string> { "剑", "药水", "护甲" };
// 序列化为JSON字符串(prettyPrint=true格式化,便于调试)
string jsonData = JsonUtility.ToJson(playerData, prettyPrint: true);
Debug.Log(jsonData);
输出结果如下(格式化后的JSON):
{
"playerName": "Alice",
"level": 10,
"health": 85.5,
"inventory": [
"剑",
"药水",
"护甲"
]
}
步骤3:将JSON字符串写入持久化存储路径
序列化后的JSON字符串需要写入持久化存储路径,才能在游戏重启后依然存在,Unity提供了Application.persistentDataPath属性,它指向设备上可读写的目录(不同平台路径不同,如Windows下为C:\Users\用户名\AppData\LocalLow\公司名\游戏名),是存储游戏数据的推荐路径。
通过File.WriteAllText()方法将JSON字符串写入文件:
using System.IO; // 需引入System.IO命名空间
string filePath = Path.Combine(Application.persistentDataPath, "playerData.json");
File.WriteAllText(filePath, jsonData);
Debug.Log("数据已保存至: " + filePath);
运行后,在Application.persistentDataPath路径下会生成playerData.json即为序列化后的JSON数据。
完整代码示例:一键保存玩家数据
将上述步骤整合为一个完整脚本,挂载到Unity场景中的任意物体(如空物体DataManager)上,即可实现一键保存功能:
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class PlayerDataSaver : MonoBehaviour
{
public void SavePlayerData()
{
// 1. 准备数据
PlayerData playerData = new PlayerData
{
playerName = "Bob",
level = 15,
health = 100f,
inventory = new List<string> { "弓", "箭", "治疗术" }
};
// 2. 序列化为JSON
string jsonData = JsonUtility.ToJson(playerData, prettyPrint: true);
// 3. 写入文件
string filePath = Path.Combine(Application.persistentDataPath, "playerData.json");
File.WriteAllText(filePath, jsonData);
Debug.Log("玩家数据保存成功!文件路径:" + filePath);
}
}
在Unity编辑器中,可以通过按钮触发保存:创建一个UI按钮,在OnClick()事件中绑定PlayerDataSaver脚本的SavePlayerData()方法,运行游戏后点击按钮即可保存数据。
进阶技巧:处理复杂数据结构与异常
保存嵌套对象与数组
如果数据类中包含另一个自定义对象(如角色的装备信息),只需将嵌套类也标记为[Serializable]即可:
[System.Serializable]
public class Equipment
{
public string weapon;
public string armor;
}
[System.Serializable]
public class PlayerData
{
public string playerName;
public Equipment equipment; // 嵌套对象
public int[] skillLevels; // 数组
}
// 使用示例
PlayerData playerData = new PlayerData
{
playerName = "Charlie",
equipment = new Equipment { weapon = "火焰剑", armor = "龙鳞甲" },
skillLevels = new int[] { 1, 3, 5 }
};
序列化结果会自动包含嵌套对象和数组:
{
"playerName": "Charlie",
"equipment": {
"weapon": "火焰剑",
"armor": "龙鳞甲"
},
"skillLevels": [
1,
3,
5
]
}
保存Dictionary类型
UnityJSON不支持直接序列化Dictionary,但可以通过List< KeyValuePair<TKey, TValue>>间接实现,例如保存玩家技能名与等级的映射:
using System.Collections.Generic;
using System.Linq;
[System.Serializable]
public class SkillData
{
public List<string> skillNames; // 键列表
public List<int> skillLevels; // 值列表
// 将Dictionary转换为List列表
public void SetDictionary(Dictionary<string, int> skillDict)
{
skillNames = skillDict.Keys.ToList();
skillLevels = skillDict.Values.ToList();
}
// 将List列表转回Dictionary
public Dictionary<string, int> GetDictionary()
{
var dict = new Dictionary<string, int>();
for (int i = 0; i < skillNames.Count; i++)
{
dict[skillNames[i]] = skillLevels[i];
}
return dict;
}
}
// 使用示例
var skillDict = new Dictionary<string, int> { { "火球术", 2 }, { "冰霜箭", 1 } };
SkillData skillData = new SkillData();
skillData.SetDictionary(skillDict);
// 序列化SkillData
string jsonData = JsonUtility.ToJson(skillData, prettyPrint: true);
异常处理:避免文件写入失败
文件写入可能因权限不足、路径无效等原因失败,需通过try-catch捕获异常并提示:
public void SaveDataWithExceptionHandling(string jsonData, string filePath)
{
try
{
File.WriteAllText(filePath, jsonData);
Debug.Log("数据保存成功!");
}
catch (System.Exception e)
{
Debug.LogError("数据保存失败: " + e.Message);
}
}
数据验证与格式化:确保文件可读性
压缩JSON(节省空间)
如果JSON数据较大,可通过prettyPrint: false减少字符串长度(移除空格和换行),节省存储空间:
string compactJson = JsonUtility.ToJson(playerData, prettyPrint: false);
加密JSON(保护敏感数据)
对于密码、充值记录等敏感数据,建议在序列化后进行加密(如AES、Base64),再写入文件:



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