Deserialize Json into list.,how to deserialize a list via .FromJson

Hi,

I have a problem while deserializing a list, that contains user-type class objects. I successfully serialize the list to a JSON file. However, I cannot load it nor do I get an error. So, here is the PlayerData.cs script that contains player information:


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

[System.Serializable]
public class PlayerData
{
    public GameObject saveAnnouncer; // This line was added to match the order of variables with CharacterDataTracker.cs.

    // Player Data
    public int currentHealth = 3;
    public int maxHealth = 3;
    public int currentCoins = 1;

    public List<Gun> equiptedGuns;
}

Here, you can see DataSaver.cs script file that converts data to JSON and from JSON:

using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic;

public static class DataSaver
{
    private static readonly string SAVE_FOLDER = Application.dataPath + "/Save/";
    
public static void SavePlayerData(CharacterDataTracker playerData)
    {
        if (!Directory.Exists(SAVE_FOLDER))
        {
            Directory.CreateDirectory(SAVE_FOLDER);
        }
        string jsonString = JsonUtility.ToJson(playerData);

        Debug.Log("Saved JSON => " + jsonString); // Referened in the below as '*'

        File.WriteAllText(SAVE_FOLDER + "playerData.json", jsonString);
    }

    public static PlayerData LoadPlayerData()
    {
        if (!Directory.Exists(SAVE_FOLDER))
        {
            Directory.CreateDirectory(SAVE_FOLDER);
        }

        if (File.Exists(SAVE_FOLDER + "playerData.json"))
        {
            string jsonString = File.ReadAllText(SAVE_FOLDER + "playerData.json");

            Debug.Log("Loaded JSON => " + jsonString); // Referened in the below as '**'

            PlayerData m_playerData = JsonUtility.FromJson<PlayerData>(jsonString);
            if (m_playerData == null)
            {
                Debug.LogError("The" + m_playerData + "is null. Returning [null].");
                return null;
            }
            else
            {
                Debug.Log(m_playerData.currentHealth + "/" + m_playerData.maxHealth + "/" + m_playerData.currentCoins); // Referened in the below as '***'

                foreach (Gun index in m_playerData.equiptedGuns)
                    Debug.Log("The Gun of DataSaver =>" + index); // Referened in the below as '****'
                
                return m_playerData;
            }
        }
        return null;
    }
}

Whenever I save the player data using DataSaver.cs, the Debug.Log(jsonString) (aka ‘*’) prints following log message:

Saved JSON =>
{“saveAnnouncer”:{“instanceID”:14614},“currentHealth”:95,“maxHealth”:100,“currentCoins”:22,“equiptedGuns”:[{“instanceID”:-1514},{“instanceID”:-26102},{“instanceID”:-26114}]}

So, it is saved into a .json file.


Whenever I try to load from the JSON file using DataSaver.cs, Debug.Log(jsonString) (aka **) prints following log message:

Loaded JSON =>
{“saveAnnouncer”:{“instanceID”:14614},“currentHealth”:95,“maxHealth”:100,“currentCoins”:22,“equiptedGuns”:[{“instanceID”:-1514},{“instanceID”:-26102},{“instanceID”:-26114}]}


According to these two log messages, I’m able to save and load the data into the JsonUtility object.
But, if I print the members of the return value of JsonUtility.FromJson(jsonString);, I see following log messages:

95/100/22 (aka ‘***’)

And

The Gun of DataSaver =>Pistol (Gun) (aka ‘****’)

The Gun of DataSaver =>

The Gun of DataSaver =>


According to the last two log messages, I can convert primitive types but cannot convert the list.


By the way, the Gun class has the following members:

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


public class Gun : MonoBehaviour
{
    public static Gun instance;

    [Header("Bullets")]
    public GameObject bulletToFire;
    public Transform firePoint;

    [Header("Fire System")]
    public float timeBetweenShots;
    private float shotCounter;

    [Header("Weapon System")]
    public string weaponName;
    public Sprite gunUI;

    [Header("Shop System")]
    public int itemCost;
    public Sprite gunShopSprite;

    private void Awake()
    {
        instance = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (PlayerController.instance.canMove && !LevelManager.instance.isPaused)
        {
            if (shotCounter > 0)
            {
                shotCounter -= Time.deltaTime;
            }
            else
            {
                if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
                {
                    Instantiate(bulletToFire, firePoint.position, firePoint.rotation);
                    shotCounter = timeBetweenShots;
                    AudioManager.instance.PlaySFX(12);
                }
            }
        }
    }
}

To sum it up, I cannot convert user-type class objects from JSON string into a list, that contains them. I hope I could tell the point where I need help.

Thank you for reading up until this point,

Have a nice night.

You’re saving and loading GameObject references in the form of instance IDs, which in my experience isn’t reliable. I’d suggest instead assigning a unique ID (string) to each gun, then saving that ID to file. When you load, pass the value to a managing class that has a dictionary<string, Gun> for easily retrieving the corresponding GO.

Also, try just opening the text file your game has created rather than printing it to console. If you use Notepad++ you can format it as JSON for easy reading, and it’ll notify you whenever it detects changes to the file.