【问题标题】:How to deserialize string for unity JsonUtility.fromJson() method, properly [duplicate]如何正确反序列化统一JsonUtility.fromJson()方法的字符串[重复]
【发布时间】:2018-05-02 20:25:10
【问题描述】:

好的,所以基本上我正在尝试从字符串中获得反序列化和序列化 C#(统一)中的自定义类的窍门。 Json 似乎是显而易见的方法,并且可以与我计划用来存储玩家数据的 mysql 一起使用。

我无法通过我试图运行的测试字符串示例来创建一个“虚拟”playerdata 对象。从那里我将在登录时将播放器对象传递给播放器上的 Initialize 方法。

我再次尝试使用(虚拟)字符串(mysql 查询的结果对吗?)来生成玩家数据对象。这就是我所拥有的。

PlayerData.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PlayerData
{
    public string Name {get; protected set;}
    public uint Attack {get; protected set;}
    public uint Defense {get; protected set;}
    public uint Armor {get; protected set;}
    public uint MovementSpeed {get; protected set;}
    public uint MagicLevel {get; protected set;}

    public static PlayerData Serialize(string obj)
    {
      return JsonUtility.FromJson<PlayerData>(obj);
    }
}

我用来运行它的代码是这样的:

String test = @"{
    ""Name"": ""Chase"",
    ""Attack"" : 50,
    ""Defense"" : 35,
    ""Armor"" : 12,
    ""MovementSpeed"" : 60,
    ""MagicLevel"" : 15,
}";
PlayerData data = PlayerData.Serialize(test);
Debug.Log(data.Attack);

我得到的错误是这样的。

ArgumentException:JSON 解析错误:缺少对象成员的名称。

我在这里真的需要帮助,我尝试用双引号封装 int 变量,尝试对所有值做同样的事情,地狱我尝试了很多方法,每次都是错误或无效值。任何帮助将不胜感激。

【问题讨论】:

  • 为什么要自己创建字符串而不是序列化现有对象?此外,您的措辞倒置。序列化是object -&gt; json,反序列化是json -&gt; object
  • 计划是从查询到 mysql 构建一个字符串以收集数据,然后将该字符串传递给 playerdata 类的静态方法,以使用查询提供的数据生成 playerdata 实例。所以我不会有实际的 JSON 文件,只有从数据库中提取的值。
  • 您不应该构建字符串,序列化/反序列化的全部意义在于使用对象。您可以从 MySql 中收集您需要的值,但您需要将这些值添加到一个对象中,然后将该对象序列化以获取 JSON。
  • 我正在反序列化,我只是错误地命名了我的方法。我有字符串格式的 JSON,我想把它变成一个对象。 json -> 对象...反序列化。
  • 我可以从你反序列化的代码中看出,我只是想让你知道它不应该被称为Serialize()。别担心,我明白了

标签: c# json unity3d deserialization


【解决方案1】:

你有两个问题。第一个是 Unity 不喜欢MagicLevel 后面的逗号。删除:

String test = @"{
    ""Name"": ""Chase"",
    ""Attack"" : 50,
    ""Defense"" : 35,
    ""Armor"" : 12,
    ""MovementSpeed"" : 60,
    ""MagicLevel"" : 15
}";

第二个问题是因为您的属性有protected set。这意味着 Unity 永远无法分配这些值,因为 JsonUtility.FromJson() 不是您的 PlayerData 类或继承自它的类,因此它无权设置这些属性。

我了解您希望防止这些属性被序列化(或以后的构造函数)以外的任何东西设置。具体来说,要统一执行此操作,您需要 [SerializeField] 属性:

[System.Serializable]
public class PlayerData
{
    [SerializeField]
    protected string _name 
    
    public string Name {get { return _name;}}

    [SerializeField]
    protected uint _attack;
    
    public uint Attack {get { return _attack;}}

    [SerializeField]
    protected uint _defense;
    
    public uint Defense {get { return _defense;}}

    [SerializeField]
    protected uint _armor;
    
    public uint Armor {get { return _armor;}}

    [SerializeField]
    protected uint _movementSpeed;
    
    public uint MovementSpeed {get { return _movementSpeed;}}

    [SerializeField]
    protected uint _magicLevel;
    
    public uint MagicLevel {get { return _magicLevel;}}

    public static PlayerData Deserialize(string obj)
    {
        return JsonUtility.FromJson<PlayerData>(obj);
    }
}

我将您的 Serialize() 方法重命名为 Deserialize(),因为它实际上是这样做的。

编辑

根据您的反复试验,Unity 似乎在序列化属性方面存在问题。这是不幸的,因为属性是处理对象中数据的设置和获取的首选方式。我已经编辑了我的示例代码以反映具有公共属性的受保护字段

【讨论】:

  • 该死的人,我是如此充满希望,但它没有奏效。完全相同的错误。 ArgumentException:JSON 解析错误:缺少对象成员的名称。
  • 序列化字段只是让它在编辑器中可见。不做任何其他事情。
  • @Codinablack 当你执行序列化时它也会序列化私有属性。
  • @Codinablack 如果您使用的 JSON 与您在问题中包含的不同,您能否发布它?
  • 试过删除所有受保护的关键字,结果还是一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 2013-04-25
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多