Node服务端返回的JS对象在Unity中反序列化失败如何解决
问题根因
- 你定义的
DictPlayers和Players外层类包含名为players的字段,但你拿到的JSON根结构直接是{"1":{...},"2":{...}}的键值对,没有外层的players包裹节点,字段无法匹配 - Unity 自带的
JsonUtility不支持Dictionary类型的序列化/反序列化,属于官方明确标注的功能限制,所以用DictPlayers接收必然返回空结果 - 你用Newtonsoft Json返回空的核心原因是用了嵌套了
players字段的外层类,和JSON结构不匹配
解决方案
方案1:使用Newtonsoft Json for Unity(推荐)
无需自定义外层包裹类,直接将根JSON反序列化为Dictionary<string, Player>即可:
- 调整Player类定义(可选,如果不想额外加Vector3转换器可以先定义Position辅助类)
[Serializable] public class Player { public string name; public int score; public int character; public int id; // 要么用辅助类接收,后续手动转Vector3,要么加Newtonsoft的Vector3转换器 public Position position; } [Serializable] public class Position { public float x; public float y; public float z; }
- 反序列化代码:
using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; // 直接反序列化根字典 Dictionary<string, Player> playerDict = JsonConvert.DeserializeObject<Dictionary<string, Player>>(payload); // 需要List的话直接取Values转List即可 List<Player> playerList = playerDict.Values.ToList();
如果要直接让position字段映射为Unity的Vector3,可以添加官方提供的Vector3转换器:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new Newtonsoft.Json.UnityConverters.Math.Vector3Converter()); Dictionary<string, Player> playerDict = JsonConvert.DeserializeObject<Dictionary<string, Player>>(payload, settings); // 此时Player类的position字段可以直接定义为public Vector3 position;
方案2:使用Unity自带JsonUtility
需要协调服务端修改JSON结构,外层增加players节点,同时将内容改为数组格式:
{ "players": [ { "id":1, "name":"John", "score":0, "character":0, "position":{"x":0,"y":1.069696307182312,"z":0} }, { "id":2, "name":"Matt", "score":0, "character":0, "position":{"x":0,"y":1.069696307182312,"z":0} } ] }
修改后直接用你原本定义的Players类即可正常反序列化:
Players networkPlayers = JsonUtility.FromJson<Players>(payload);
如果服务端无法修改结构,不建议强用JsonUtility,自行解析的成本远高于引入Newtonsoft Json。
内容的提问来源于stack exchange,提问作者Miika Anundi
相关产品推荐
相关产品推荐

