在序列化时获取空JsonUtility

时间:2018-02-15 22:36:56

标签: c# unity3d

我刚刚进入JsonUtility的整个包装方面,我遇到了一个小问题。当我看着 RewardItem 时,他们似乎总是空着。这是我的课程。

[Serializable]
public class QuestData {

    public int ID;
    public string Name;
    public int MinimumLevel;
    public int[] QuestsNeeded;
    public string Description;
    public string ShortDescription;
    public string WaitingDialogue;
    public string FinishedDialogue;
    public int Experience;
    // The Items received from the quest.
    public RewardItem ChooseItemData;
    public RewardItem RewardItemData;
    public string QuestType;
    public KillType QuestKillCount;
    public TalkType QuestTalk;
    public bool Retired;

    /// <summary>
    /// Quest Data for a Kill Quest.
    /// </summary>
    public QuestData (int id, string questName, int minlevel, string questsNeeded, string description, string shortDescription, string waitingDialogue, string finishedDialogue, 
        int experience, string rewardItemIDs, string rewardItemAmounts, string chooseItemIDs, string chooseItemAmounts, string questType, string killNames, string killAmounts, 
        string talkNpcNames, string talkSceneNames, bool isRetired) {

        this.ID = id;
        this.Name = questName;
        this.MinimumLevel = minlevel;
        this.QuestsNeeded = Array.ConvertAll(questsNeeded.Split(','), int.Parse);
        this.Description = description;
        this.ShortDescription = shortDescription;
        this.WaitingDialogue = waitingDialogue;
        this.FinishedDialogue = finishedDialogue;
        this.Experience = experience;
        this.QuestType = questType;
        this.Retired = isRetired;

        // IF we dont have an empty string letting us know we want to give rewards this way,
        // ELSE we have an empty string so we make a empty RewardItem.
        if (!String.IsNullOrEmpty (rewardItemIDs)) {
            this.RewardItemData = new RewardItem (Array.ConvertAll (rewardItemIDs.Split (','), int.Parse), Array.ConvertAll (rewardItemAmounts.Split (','), int.Parse));
        } else {
            this.RewardItemData = new RewardItem ();
        }

        // IF we dont have an empty string letting us know we want to give rewards this way,
        // ELSE we have an empty string so we make a empty Choose Reward Item.
        if (!String.IsNullOrEmpty (chooseItemIDs)) {
            this.ChooseItemData = new RewardItem (Array.ConvertAll (chooseItemIDs.Split (','), int.Parse), Array.ConvertAll (chooseItemAmounts.Split (','), int.Parse));
        } else {
            this.ChooseItemData = new RewardItem ();
        }

        // IF we dont have an empty string letting us know we have a Kill Quest,
        // ELSE no kill quest.
        if (!String.IsNullOrEmpty (killNames)) {
            this.QuestKillCount = new KillType (killNames.Split (','), new int[killNames.Split(',').Length], Array.ConvertAll(killAmounts.Split(','), int.Parse));
        } else {
            this.QuestKillCount = new KillType ();
        }

        // IF we dont have an empty string letting us know we have a Talk Quest,
        // ELSE no talk quest.
        if (!String.IsNullOrEmpty (talkNpcNames)) {
            this.QuestTalk = new TalkType (talkNpcNames.Split (','), talkSceneNames.Split (','));
        } else {
            this.QuestTalk = new TalkType ();
        }
    }
}

这里的 Quest_List 代码是我放入JsonUtility方法然后保存到PlayerPrefs的。

[Serializable]
public class Quest_List {
    // The Lists of quests that fall into the Accepted section.
    public List<QuestData> questAccepted = new List<QuestData> ();
    public List<QuestData> questReadyToTurnIn = new List<QuestData> ();
    public List<QuestData> questCompleted = new List<QuestData> ();
    // The Lists of quests that fall into the Not Accepted section.
    public List<QuestData> questAcceptable = new List<QuestData> ();
    public List<QuestData> questSoon = new List<QuestData> ();
    public List<QuestData> questTooHigh = new List<QuestData> ();
}

我的班级用于奖励。

[Serializable]
public class RewardItem {

    private int[] rewardItemIDs;
    private int[] rewardItemAmounts;

    public RewardItem (int[] itemID, int[] itemAmount) {
        this.rewardItemIDs = itemID;
        this.rewardItemAmounts = itemAmount;
    }

    public RewardItem () {
        this.rewardItemIDs = new int[0];
        this.rewardItemAmounts = new int[0];
    }

    public int[] GetItemIDs () {
        return this.rewardItemIDs;
    }

    public int[] GetItemAmounts () {
        return this.rewardItemAmounts;
    }
}

我目前使用的包装器:

    public static class JsonHelper {

    public static string ToJson<T> (T items) {

        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = items;
        return JsonUtility.ToJson(wrapper, true);
    }

    [Serializable]
    private class Wrapper<T> {

        public T Items;
    }
}

我如何初始化我的数据库。

private void ConstructQuestDatabase (int level) {
    // Loop the amount of quest we have.
    for (int i = 0; i < questJsonData.Count; i++) {
        // Add to our Quest Data.
        questDatabase.Add (new QuestData (
            QuestDataInt (i, "id"),
            QuestDataString (i, "name"), 
            QuestDataInt (i, "minimumlevel"),
            QuestDataString (i, "questsneeded"),
            QuestDataString (i, "description"),
            QuestDataString (i, "shortdescription"),
            QuestDataString (i, "waitingdialogue"),
            QuestDataString (i, "finishdialogue"),
            QuestDataInt (i, "experience"),
            QuestDataString (i, "ChooseItemData"),
            QuestDataString (i, "RewardItemData"),
            QuestDataString (i, "questtype"),
            QuestDataString (i, "killtype", "name"),
            QuestDataString (i, "killtype", "amount"),
            QuestDataString (i, "talktype", "npcname"),
            QuestDataString (i, "talktype", "scenename"),
            QuestDataBool (i, "retired")
        ));
    }
}

现在我使用上述类的方法/代码:

public void Save () {               
    Quest_List questContainer = new Quest_List ();
    questContainer.questAccepted = questAccepted;
    questContainer.questReadyToTurnIn = questReadyToTurnIn;
    questContainer.questCompleted = questCompleted;
    string questToJson = JsonHelper.ToJson (questContainer);
    // Save the information.
    PlayerPrefs.SetString ("Quest_Status", questToJson);

    print (questToJson);
}

这是我在打印时看到的内容:

enter image description here

现在,如果我们查看 QuestAccepted 部分,您会在该图片中看到4个为空(2个奖励和基于杀戮和谈话的任务),我知道当我解决问题时我可以把它应用到其他的那些但是目前我无法弄清楚如何让那部分不是空的。

1 个答案:

答案 0 :(得分:2)

你的两个变量:

private int[] rewardItemIDs;
private int[] rewardItemAmounts;

正在返回null,因为它们被声明为private。除非您为它们添加特殊属性,否则Unity无法序列化private属性。

您有两种选择:

1 。制作变量public

public int[] rewardItemIDs;
public int[] rewardItemAmounts;

2 。将它们保存为private,但为每个[SerializeField]变量添加private属性。请注意,这与类/结构/枚举上方添加的[Serializable]不同。

[SerializeField]
private int[] rewardItemIDs;
[SerializeField]
private int[] rewardItemAmounts;

这也应该适用于你的另外2个具有相同问题的变量,但由于它们没有发布,我无法判断它们是否是同一个问题。

请参阅我的other帖子中的 4.TROUBLESHOOTING JsonUtility:,其中显示了使用JsonUtility时可能会出现空值的原因。我还将更新该帖子以包含此答案中的内容。