如何正确反序列化JsonUtility.fromJson()方法的字符串

时间:2018-05-02 20:25:10

标签: c# json unity3d deserialization

好的,基本上我试图从字符串中取消序列化和序列化C#(unity)中的自定义类。 Json似乎是一种显而易见的方法,并且可以用于我计划用来存储播放器数据的mysql。

我无法通过测试字符串示例我正试图制作一个" Dummy" 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变量进行封装,尝试对所有值做同样的事情,地狱我尝试了很多方法,每次都是错误或无效值。请大家帮忙。

1 个答案:

答案 0 :(得分: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似乎对序列化属性产生了问题。这是不幸的,因为属性是处理对象中数据设置和获取的首选方式。我编辑了我的示例代码以反映具有公共属性的受保护字段