【问题标题】:How do we parse JSON in Unity3d?我们如何在 Unity3d 中解析 JSON?
【发布时间】:2021-01-05 09:12:12
【问题描述】:

当我尝试使用 JsonUtility 从返回元素数组的 REST 调用中解析 JSON 时,它无法说明顶层必须是一个对象。来吧,伙计们。太可笑了。

好的,继续研究如何使用 Newtonsoft.json,因为它在其他任何地方都能正常工作。

尝试在资产商店之外使用 JSON .NET for Unity。似乎它可以正常工作并且在编辑器中可以正常工作,但是当我尝试在我的 dev macbook pro 上的 Mac 本地构建中使用它时,它不起作用(调用它失败但有异常)。因此,如果它在我的开发机器和 mac 版本上不起作用,那就不行了。 https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

从这里尝试使用 jilleJr 的版本:https://github.com/jilleJr/Newtonsoft.Json-for-Unity,但安装说明导致包管理器无法打开。按照说明将包直接添加到我的 manifest.json 中时,我得到一个空引用异常

那么现在让 JSON 在 Unity 2019/2020 中工作的秘诀是什么?对于一个平台来说,这似乎是一个巨大的问题。

【问题讨论】:

    标签: json unity3d json.net


    【解决方案1】:

    打开 *YourUnityProject*/Packages/manifest.json 并将以下行添加到 dependencies 对象。

    "com.unity.nuget.newtonsoft-json": "2.0.0",
    

    要序列化和反序列化数据,请使用以下函数:

    using Newtonsoft.Json;
    
    public class Data
    {
        int[] numbers;
    }
    
    string json = JsonConvert.SerializeObject(new Data());
    Data data = JsonConvert.DeserializeObject<Data>(json);
    

    【讨论】:

    • 我看到 Unity 添加了对 JSON.net 的支持。非常聪明。能不能把using语句“using Newtonsoft.Json”加到你的代码sn-p上面的类声明上面,我想大家都会明白的,所以我把它标记为答案。
    • 另外,您知道这是否也适用于 Unity 2019 还是仅适用于 2020 年?我认为因为它是一个 nuget 包,所以它在 2019 年也可以正常工作。
    • @Brian 不确定 2019 年,我只使用 2020 年。
    • 好的,现在已经足够了。我们自己使用 2020 年。只是想知道。标记为答案。非常感谢您的帮助。我们已经尝试过了,效果很好。
    • 我们确实有一个相关的问题,即在使用光子网络时如何使用 com.unity.nuget.newtonsoft-json。所以,我们还没有完全走出困境,但我认为这个关于使用 Unity 的 newtonsoft 包的答案现在很好。关于与 Photon 冲突的问题在另一个 stackoverflow 帖子中:stackoverflow.com/questions/63957972/…
    【解决方案2】:

    当我试图从序列化的 JSON 中读取数据时,我不会说这是 Unity 的问题。 JsonUtility 在对类进行序列化/反序列化时工作得很好。我也更喜欢 Newtonsoft.json,主要是因为它是 UnityEngine 的一部分

    例如:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    
    public class JSONRW : MonoBehaviour
    {
        PersonData data;
        string jsonPath = "Assets/TestJSON.json";
    
        private void Start()
        {
            //Read in JSON file
            string jsonString = File.ReadAllText(jsonPath);
            data = JsonUtility.FromJson<PersonData>(jsonString);
    
            Debug.Log(data.client[0].name); //Outputs A
    
            //Write to JSON file
            data.client[0].name = "Luc"; //Changes the name of the entry named A
            File.WriteAllText(jsonPath, JsonUtility.ToJson(data)); //Writes updata back to file
        }
    }
    
    [System.Serializable]
    public class Person
    {
        public string name;
        public int age;
        public Person(string _name, int _age)
        {
            name = _name;
            age = _age;
        }
    }
    
    [System.Serializable]
    public class PersonData
    {
        public List<Person> client;
    }
    
    

    JSON 文件:

    {
      "client": [
        {
          "name": "A",
          "age": 10
        },
        {
          "name": "B",
          "age": 20
        },
        {
          "name": "C",
          "age": 30
        },
        {
          "name": "D",
          "age": 40
        }
      ]
    }
    
    

    【讨论】:

    • 我使用过 JsonUtility,对于一些简单的事情还可以,但我们很快就遇到了问题。不支持顶级数组,也不支持 DateTime 元素。我没有更进一步,因为我们专门处理作为查询结果的数据列表,并且我们有很多 DateTime 信息。
    • 我在 JsonUtility 存储 DateTime 数据方面没有遇到任何问题,我现在不在我的电脑旁,但我稍后可能会展示一个示例。对于顶级数组我不确定,但我不明白为什么它不起作用
    • 绝对不适用于顶级数组。有关于它的帖子。可能是我们的 DateTime 元素可以为空,但它遇到了问题,我不得不将它们视为字符串。
    • 嗨 Luc,我跟进了日期时间问题。我们发现,当我们向服务器发布一个包含 DateTime 字段的对象时,实际上是一个可为空的“DateTime?” JsonUtility.ToJson 实际上并没有把它放在对象中发送到服务器,我们在服务器端收到了空值。我们将字段的数据类型更改为字符串,并使用 myDatetime.ToString("o") 将字段序列化为标准 ISO 格式并将字符串发送到服务器,然后就可以了。
    • 与其将DateTime? 更改为字符串,不如发送一个无效的日期时间,例如new DateTime(0000, 00, 00);,这在将来可能更易于解释,而不是在DateTime 和字符串之间进行转换
    猜你喜欢
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    相关资源
    最近更新 更多