You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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也能轻松集成:

  1. 在Unity的Package Manager里,选择Add package from git URL,输入com.unity.nuget.newtonsoft-json安装;或者直接导入官方提供的dll。

  2. 代码示例:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:23:59