如何使用 C# 在 Unity 中解析复杂的 JSON 对象

^--- 对于断言问题只是重复的断言的反驳,请参见底部的注释。


剧透:根据 carldevelopsforcoffee 接受的有效答案,请参阅问题底部的最终代码。

原始问题:

我正在尝试使用 UnityEngine.JsonUtility.FromJson() 在 Unity(2018.1,VS2015,如果重要)中使用 C# 解析复杂的 JSON 文件(见下文)。解析器代码如下所示。


顶级变量(sweepIndex、totalRadials 等)都可以很好地解析到 Sweep 对象中,但“radials”数组似乎被跳过了(Sweep 中的 Radial 对象列表最终为空)。


如果从 JSON 中不明显,它具有以下结构:


具有 13 个简单值和一组 Radial 对象的顶级“Sweep”对象。


List 中的每个 Radial 对象都有 4 个简单值和一个双精度数组


格式化 JSON 以说明结构:

(为清楚起见,已编辑和截断......完整的 JSON 是下面类中的字符串)


{"sweepIndex":0,

"totalRadials":720,

"beamWidth":0.949999988079071,

"startingUnixtime":1536864392000,

"endingUnixtime":1536863574000,

"totalGatesPerRay":1832,

"gateDepthMeters":250.0,

"distanceToFirstGateMeters":2125.0,

"meanElevationDeg":0.5275726318359375,

"originLatitude":33.989444444444445,

"originLongitude":-78.42888888888889,

"originAltitude":20.0,

"deviantOriginCount":0,

"radials": [

    {"radialNumber":0,"azimuthDeg":263.21319580078125,"elevationDeg":0.53009033203125,"duration":66521592,

        "gateIntensity":[-5.5,-1.0,1.0,3.0,13.5,-15.0,-13.0,-11.5,-10.5,-7.5]},

    {"radialNumber":1,"azimuthDeg":263.7432861328125,"elevationDeg":0.5328369140625,"duration":66521616,

        "gateIntensity":[-9.5,-1.0,-4.5,-2.5,5.0,-4.0,9.0,-8.5,-1.5,-9.0]}

]}

我是生成 JSON 文件的人(使用 Netcdf-Java 吸入原始的 2 级雷达数据并将其作为 JSON 吐出以供 Unity 应用程序使用),所以如果 JSON 极大地改善了我的生活,我可能会更改它更容易......但我真的更喜欢不大幅改变整体结构(使用带有双精度数组的径向对象数组的扫描对象)。

笔记:

用户“程序员”表示这是一个所谓的重复的问题的答案实际上并不能解决我所说的问题 - Unity中的复杂JSON 。它确定 Unity 内置的 JsonUtility 类不足以解析复杂的 JSON,同时没有提供真正的替代方案。

关于将第三方 Json 库与 C# 一起使用的问题存在于 SO 上……但在 Unity 项目中使用第三方库和 C#如果它们尚未作为 .unitypackage 提供,则它们的任务更加困难和具体特别是如果它最终需要能够在 Windows 以外的平台上运行(例如,Android、Magic Leap、Oculus 等)。

这就是为什么这个问题的公认答案很有价值,并为 SO 作为一种资源增加了具体价值......它确定了一个解决问题的三个具体问题的解决方案——复杂的 Json、C#,让它在 Unity 中的平台中工作-不可知论的方式。


UYOU
浏览 325回答 3
3回答

湖上湖

复制粘贴你的 json 和http://json2csharp.com/你会得到这个:public class Radial{&nbsp; &nbsp; public int radialNumber { get; set; }&nbsp; &nbsp; public double azimuthDeg { get; set; }&nbsp; &nbsp; public double elevationDeg { get; set; }&nbsp; &nbsp; public int duration { get; set; }&nbsp; &nbsp; public List<double> gateIntensity { get; set; }}public class RootObject{&nbsp; &nbsp; public int sweepIndex { get; set; }&nbsp; &nbsp; public int totalRadials { get; set; }&nbsp; &nbsp; public double beamWidth { get; set; }&nbsp; &nbsp; public long startingUnixtime { get; set; }&nbsp; &nbsp; public long endingUnixtime { get; set; }&nbsp; &nbsp; public int totalGatesPerRay { get; set; }&nbsp; &nbsp; public double gateDepthMeters { get; set; }&nbsp; &nbsp; public double distanceToFirstGateMeters { get; set; }&nbsp; &nbsp; public double meanElevationDeg { get; set; }&nbsp; &nbsp; public double originLatitude { get; set; }&nbsp; &nbsp; public double originLongitude { get; set; }&nbsp; &nbsp; public double originAltitude { get; set; }&nbsp; &nbsp; public int deviantOriginCount { get; set; }&nbsp; &nbsp; public List<Radial> radials { get; set; }}然后你可以使用 JsonUtility 但你首先需要修改一些内容。将 Serializable 属性添加到每个类并删除属性扩展以生成这些基本变量。[Serializable]public class Radial{&nbsp; &nbsp; public int radialNumber;&nbsp; &nbsp; public double azimuthDeg;&nbsp; &nbsp; public double elevationDeg;&nbsp; &nbsp; public int duration;&nbsp; &nbsp; public List<double> gateIntensity;}[Serializable]public class RootObject{&nbsp; &nbsp; public int sweepIndex;&nbsp; &nbsp;// same with all following items}RootObject 是您的 json 的顶级类,它在 json 中没有名称,因此会生成默认值。您可以将 RootObject 更改为您想要的任何内容,例如 JsonResponse。现在可以像这样使用了:void Start(){&nbsp; &nbsp; &nbsp;string json = GetJsonFile(); // From download or text file&nbsp; &nbsp; &nbsp;RootObject ro = JsonUtility.FromJson<RootObject>(json);&nbsp; &nbsp; &nbsp;print( ro.radials[0].radialNumber);&nbsp;}

茅侃侃

我在 Unity 中将JsonFx用于我的数据类。示例类:using JsonFx.Json;[Serializable][JsonName("MyData")]public class MyData{&nbsp; &nbsp; public int id;&nbsp; &nbsp; public string name;&nbsp; &nbsp; public int[] stuff;}示例 json:{&nbsp; &nbsp; "__Type": "MyData, Assembly-CSharp",&nbsp; &nbsp; "id": 1,&nbsp; &nbsp; "name": "new_data",&nbsp; &nbsp; "stuff" :&nbsp; &nbsp; &nbsp; &nbsp;[&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2&nbsp; &nbsp; &nbsp; &nbsp; ]&nbsp;}从 json 创建数据对象:// Json to MyData object:&nbsp;// Assume I downloaded a json filestring jsonData = System.Text.Encoding.UTF8.GetString (www.bytes);jsonData = jsonData.Trim ();MyData data = MyData.Deserialize(jsonData);从数据对象创建 json 文件// MyData object to Json// Use MyData data objectstring file = "mydata.json";JsonWriterSettings settings = new JsonWriterSettings ();settings.PrettyPrint = true;settings.TypeHintName = "__Type";JsonWriter writer = new JsonWriter (file, settings);writer.Write (data);writer.TextWriter.Flush ();writer.TextWriter.Close ();

慕标5832272

例如,有一个在线服务可以自动从 Json 转换为 Pocohttp://json2csharp.com/http://jsonutils.com/https://quicktype.io/在 VisualStudio 中,还有一个菜单可以执行此操作:
打开App,查看更多内容
随时随地看视频慕课网APP