- Home /
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.
Answer by Deeje · Feb 02 at 10:09 PM
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.
I could not succeed.
I'm not able to save any weapon to JSON right now after making the following changes:
In CharacterDataTracker.cs, I declared public Dictionary myGunList; instead of public List equiptedGuns; and changed this.equiptedGuns = new List(); with this.myGunList = new Dictionary(); in the Awake() of CharacterDataTracker.cs.
In PlayerData.cs, I wrote public Dictionary myGunList; instead of public List equiptedGuns;
I think I need to learn other concepts, such as the way JSON works, before proceeding further. Currently, I feel like I'm doing it by heart. I think I need to know what's going on in the background.
Anyway, thank you for your answer.
Have a nice day/night.
Your answer
Follow this Question
Related Questions
[JsonUtility] cannot deserialize json to new instances of type X 2 Answers
JSON invalid value 1 Answer
Json.net deserialization problem 1 Answer
Deserializing dictionary with 'Json.Net' for Unity returns a null object. 0 Answers
JSON deserialization 0 Answers