2
\$\begingroup\$

i have the problem that when I convert an instance of highscores through JsonUtility.ToJson the value of my value of it is always {"highscoreEntryList":[{},{},{},{},{},{},{},{},{},{},{}]}...

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

public class HighScoreTable : MonoBehaviour
{
    private Transform entryContainer;
    private Transform entryTemplate;
    private List<HighScoreEntry> highScoreEntries;
    private List<Transform> highScoreEntryTransformList;
    private void Awake()
    {
        entryContainer = transform.Find("HighScoreEntryContainer");
        entryTemplate = entryContainer.Find("HighScoreEntryTemp");

        entryTemplate.gameObject.SetActive(false);

        highScoreEntries = new List<HighScoreEntry>() 
        {
            new HighScoreEntry { Score = 9999, Name = "T1"} ,
            new HighScoreEntry { Score = 9282, Name = "T2"} ,
            new HighScoreEntry { Score = 9942, Name = "T3"} ,
            new HighScoreEntry { Score = 2419, Name = "t4"} ,
            new HighScoreEntry { Score = 2390, Name = "t5"} ,
            new HighScoreEntry { Score = 9282, Name = "t7"} ,
            new HighScoreEntry { Score = 2918, Name = "t6"} ,
            new HighScoreEntry { Score = 4921, Name = "t8"} ,
            new HighScoreEntry { Score = 1318, Name = "t9"} ,
            new HighScoreEntry { Score = 8818, Name = "t10"} ,
            new HighScoreEntry { Score = 9231, Name = "t11"} ,
        };

        highScoreEntryTransformList = new List<Transform>();
        highScoreEntries.Sort((first, second) => second.Score.CompareTo(first.Score));

        foreach (var highScoreEntry in highScoreEntries)
            CreateHighScoreEntry(highScoreEntry, entryContainer, highScoreEntryTransformList);

        Highscores highscores = new Highscores {highscoreEntryList = highScoreEntries };
        string json = JsonUtility.ToJson(highscores);
        PlayerPrefs.SetString("highscoreTable", json);
        PlayerPrefs.Save();
        Debug.Log(PlayerPrefs.GetString("highscoreTable"));
    }

    private void CreateHighScoreEntry(HighScoreEntry highScoreEntry, Transform container, List<Transform> transformlist)
    {
        float tempHeight = 40f;
        Transform entryTransform = Instantiate(entryTemplate, container);
        RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
        entryRectTransform.anchoredPosition = new Vector2(0, -tempHeight * transformlist.Count);
        entryTransform.gameObject.SetActive(true);

        entryTransform.Find("posText").GetComponent<Text>().text = "" + (transformlist.Count + 1);
        entryTransform.Find("scoreText").GetComponent<Text>().text = "" + highScoreEntry.Score;
        entryTransform.Find("nameText").GetComponent<Text>().text = "" + highScoreEntry.Name;

        transformlist.Add(entryTransform);

    }


    private class Highscores
    {
        public List<HighScoreEntry> highscoreEntryList;
    }

    [Serializable]
    private class HighScoreEntry
    {
        public int Score { get; set; }
        public string Name { get; set; }
    }
}

My List property is public and i also tried to write [SerializeField] over it.

\$\endgroup\$
1
\$\begingroup\$

JSONUtility can serialize fields, but it can not serialize properties. As the documentation of [SerializeField] says:

The serialization system can do the following:

  • CAN serialize public non-static fields (of serializable types)
  • CAN serialize nonpublic non-static fields marked with the SerializeField attribute.
  • CANNOT serialize static fields.
  • CANNOT serialize properties.

So how do we solve this problem? The most simple solution would be to get rid of the { get; set; } parts in class HighScoreEntry.

[Serializable]
private class HighScoreEntry
{
    public int Score;
    public string Name;
}

Whether those fields are raw public fields or properties with trivial getters and setters shouldn't really change anything in this particular case. But if you really want to use properties in a serializable object for some reason, then you have to use getters and setters which encapsulate private fields marked with the [SerializeField] attribute:

[Serializable]
private class HighScoreEntry
{
    [SerializeField] private int score;
    public int Score {  get { return this.score; }
                        set { this.score = value; } }


    [SerializeField] private string name;
    public int Name {  get { return this.name; }
                       set { this.name = value; } }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.