【发布时间】:2021-02-06 23:57:36
【问题描述】:
这是一个真正的谜题。
我在 Unity 中使用 Newtonsoft.Json 序列化 HexTile 列表,其中每个列表都有一个 Hexagon,它生成的 JSON 看起来不错,并且在我的 Node 应用程序中反序列化就好了 数据来源:
PolySphere sphere = new PolySphere(Vector3.zero, WorldManager.worldScale, WorldManager.worldSubdivisions);
JsonSerializer serializer = new JsonSerializer();
serializer.Formatting = Formatting.Indented;
using (StreamWriter sw = new StreamWriter(Application.dataPath+"\\Resources\\baseworld.json")) // Note DO NOT use any encoding options
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, sphere);
}
^ 这会产生这个(好的)JSON:
{
"hexTiles": [
{
"index": 0,
"height": 0.0,
"hexagon": {
"center": {
"x": 0.561780632,
"y": 0.5952229,
"z": -0.574553967
},
"normal": {
"x": 0.561780632,
"y": 0.5952229,
"z": -0.574553967
},
"v1": {
"x": 0.561780632,
"y": 0.5952229,
"z": -0.574553967
},
"v2": {
"x": 17.0217762,
"y": 17.6508,
"z": -18.0395374
},
"v3": {
"x": 16.5437584,
"y": 18.1888123,
"z": -17.94959
},
"v4": {
"x": 16.6196823,
"y": 18.6517467,
"z": -17.3958359
},
"v5": {
"x": 17.17278,
"y": 18.5775471,
"z": -16.9318352
},
"v6": {
"x": 17.6508,
"y": 18.0395355,
"z": -17.0217762
},
"isPentagon": false,
"scale": 30.4333477
},
"type": 0,
"neighbors": [
1,
2,
3,
4,
9,
10
],
"passable": true
}
]
}
但是结果没有正确反序列化回 PolySphere。
TextAsset text = Resources.Load<TextAsset>("baseworld");
PolySphere baseWorld = JsonConvert.DeserializeObject<PolySphere>(text.text);
// The baseWorld.hexTiles[0].hexagon.center is Infinity, as shown by logging:
Debug.Log(JsonConvert.SerializeObject(baseWorld));
在Unity中^重新解析后的Debug.Log:
{"hexTiles":[
{
"index":0,"height":0.0,
"hexagon":{
"center":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"normal":{"x":0.561780632,"y":0.5952229,"z":-0.574553967},
"v1":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"v2":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"v3":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"v4":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"v5":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"v6":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
"isPentagon":false,"scale":"Infinity"
},
"type":0,
"neighbors":[1,2,3,4,9,10],
"passable":true
}
]}
polySphere.hexTiles[0].hexagon.normal 解析正确,但 center、v1、v2 等都显示为 {infinity、infinity、-infinity} 为什么?
您会注意到center、normal 和v1 都是等价的,所以我知道解析这些值不是问题。原始 JSON 的格式似乎正确并且它在 Node.js 中工作。那么这里发生了什么?
原来的类结构:
[Serializable]
public class PolySphere
{
public List<HexTile> hexTiles;
}
[Serializable]
public class HexTile
{
public int index;
public float height = 1;
public Hexagon hexagon;
public int type;
public int[] neighbors;
}
[Serializable]
public class Hexagon
{
public SerializableVector3 center, normal, v1, v2, v3, v4, v5, v6;
public bool isPentagon;
private float _scale;
public float scale { get{return _scale;}
set{
v1 /= v1.magnitude;
v1 *= value;
v2 /= v2.magnitude;
v2 *= value;
v3 /= v3.magnitude;
v3 *= value;
v4 /= v4.magnitude;
v4 *= value;
v5 /= v5.magnitude;
v5 *= value;
v6 /= v6.magnitude;
v6 *= value;
center = (v1 + v2 + v3 + v4 + v5 + v6) / 6f;
_scale = center.magnitude;
}
} }
[System.Serializable]
public struct SerializableVector3
{
public float x, y, z;
}
tl;dr 在我的 Hexagon 类中,8 个中的一个 SerializableVector3 正确反序列化,其余的都显示为 Infinity
【问题讨论】:
-
3)
FloatParseHandling控制在数据模型中未明确指定时如何解析浮点数,例如解析为JToken或dynamic时。它应该不会影响明确键入为float的属性如何从 JSON 字符串反序列化。 -
嗨@dbc,非常感谢您的关注。我已经用更详尽的例子更新了这个问题。要重现的完整源代码将有很多 MB,但我尽可能使用实际输出数据作为完整示例提供。
-
无法在 .NET Core 3.1.5 上重现,请参阅 dotnetfiddle.net/5LlWnZ。也许在解析
float字段时存在一些特定于Unity 的问题?您可以尝试将它们更改为double并重新测试吗?还是将它们更改为自动属性并重新测试? -
我尝试使用 double 和 auto 字段,降级到 Json.net 3.5 并升级到 4.5,还尝试粘贴我的问题中给出的字符串文字(带有转义引号),仍然得到相同的无穷大错误。
标签: c# json unity3d json.net deserialization