Unity-C#中JSON与Dictionary互转的问题求助
解决Unity-C#中JSON与指定Dictionary结构互转的问题
嘿,我来帮你搞定这个JSON和Dictionary互转的坑!你遇到的问题其实很典型——Unity内置的JsonUtility对泛型集合(比如Dictionary)的支持确实有限,直接解析肯定会出问题,下面给你几个实用的解决方案,从简单到自定义都有:
为什么JsonUtility直接解析Dictionary会失败?
JsonUtility是为序列化自定义类/结构体设计的,它需要明确的类型结构才能正确映射数据。直接用JsonUtility.FromJson<Dictionary<string, string>>()的话,它没法自动识别Dictionary的键值对结构,自然返回空数据啦。
方案1:用自定义包装类适配JsonUtility(无第三方库)
我们可以先定义两个序列化类,把Dictionary的结构包装起来,让JsonUtility能正确识别:
// 单个单位的数据结构,必须加[Serializable]标记 [System.Serializable] public class UnitData { public int uni_number; public int level; public int Hp; } // 包装Dictionary的容器类 [System.Serializable] public class UnitDictionaryWrapper { // 用List<KeyValuePair>来模拟Dictionary的键值对结构 public List<KeyValuePair<int, UnitData>> units = new List<KeyValuePair<int, UnitData>>(); }
解析JSON到Dictionary
// 假设你的原始JSON字符串格式对应包装类 string rawJson = "{\"units\":[{\"Key\":1,\"Value\":{\"uni_number\":1,\"level\":3,\"Hp\":15}},{\"Key\":2,\"Value\":{\"uni_number\":0,\"level\":0,\"Hp\":0}}]}"; // 先解析到包装类 UnitDictionaryWrapper wrapper = JsonUtility.FromJson<UnitDictionaryWrapper>(rawJson); // 转换成你需要的Dictionary<int, UnitData> Dictionary<int, UnitData> unitDict = new Dictionary<int, UnitData>(); foreach (var kvp in wrapper.units) { unitDict.Add(kvp.Key, kvp.Value); }
将Dictionary转回JSON存档
// 把Dictionary转成包装类的List UnitDictionaryWrapper saveWrapper = new UnitDictionaryWrapper(); saveWrapper.units = unitDict.ToList(); // 序列化成JSON字符串,prettyPrint=true让格式更易读 string saveJson = JsonUtility.ToJson(saveWrapper, prettyPrint: true); // 接下来就可以把saveJson写入存档文件啦
方案2:用Newtonsoft.Json(最省心的第三方库)
如果不想折腾包装类,直接用Newtonsoft.Json(也就是Json.NET)就行,它对Dictionary的支持非常完美,Unity也能轻松集成:
在Unity的Package Manager里,选择
Add package from git URL,输入com.unity.nuget.newtonsoft-json安装;或者直接导入官方提供的dll。代码示例:
using Newtonsoft.Json; // 解析JSON到Dictionary string rawJson = "{\"1\":{\"uni_number\":1,\"level\":3,\"Hp\":15},\"2\":{\"uni_number\":0,\"level\":0,\"Hp\":0}}"; Dictionary<int, UnitData> unitDict = JsonConvert.DeserializeObject<Dictionary<int, UnitData>>(rawJson); // 将Dictionary转回JSON存档 string saveJson = JsonConvert.SerializeObject(unitDict, Formatting.Indented);
这个方法完全不需要额外的包装类,直接一步到位,非常适合游戏存档场景。
方案3:用Unity的JsonNode(2020.3+版本支持)
如果你的Unity版本是2020.3及以上,可以用官方新增的JsonNode来直接处理动态JSON结构,不用写包装类:
using UnityEngine; // 解析JSON到Dictionary string rawJson = "{\"1\":{\"uni_number\":1,\"level\":3,\"Hp\":15},\"2\":{\"uni_number\":0,\"level\":0,\"Hp\":0}}"; JsonNode rootNode = JsonUtility.FromJson<JsonNode>(rawJson); Dictionary<int, UnitData> unitDict = new Dictionary<int, UnitData>(); foreach (var kvp in rootNode.AsObject()) { int key = int.Parse(kvp.Key); UnitData data = kvp.Value.ToObject<UnitData>(); unitDict.Add(key, data); } // 将Dictionary转回JSON存档 JsonObject saveNode = new JsonObject(); foreach (var kvp in unitDict) { saveNode[kvp.Key.ToString()] = JsonUtility.ToJsonNode(kvp.Value); } string saveJson = saveNode.ToJsonString();
总结
- 优先推荐方案2(Newtonsoft.Json),代码最简洁,兼容性最好;
- 如果不能用第三方库,选方案1或方案3,比自己写全量转换函数成本低太多;
- 避免直接用
JsonUtility解析Dictionary,这本来就不是它的设计场景。
内容的提问来源于stack exchange,提问作者MyNameIsntBob
相关产品推荐
相关产品推荐

