0

I am trying to read from a JSON file a series of items into an Object array. Unfortunately it comes back as null.

Very similar to this issue Unity C# JsonUtility is not serializing a list

So in my particular situation I have the class for the item:

[Serializable]
public class StateData
{
    public string name;
    public string location;
    public string gameText;
}

The class of the collection of items:

[Serializable]
public class StateDataCollection
{
    public List<StateData> stateDatas = new List<StateData>();
}

And the class where this is invoked:

public class JSONReader : MonoBehaviour
{
    private const string Path = @"S:\repos\myProject\Assets\gameText\";

    void Start()
    {
        string json = File.ReadAllText(Path + "StateData.json");
        StateDataCollection stateDataCollection = new StateDataCollection();
        stateDataCollection = JsonUtility.FromJson<StateDataCollection>(json);
    }
}

Finally the json

{
"StateData":[
{
"name": "name", 
"location":"location",
"gameText" : "gameText"},
{
"name": "name", 
"location":"location",
"gameText" : "gameText"},
{
"name": "name", 
"location":"location",
"gameText" : "gameText"
}]
}

The object comes back as null. The file is reading OK.

Any ideas where this is failing? TY!

Ken Pino
  • 31
  • 1
  • 3

1 Answers1

0

I would start by checking a few things first:

  • Check if the file actually exists. Just use a small Debug.Log(File.Exists(path)).
  • Try another path -> something save like: Application.persistentDataPath. On Windows this will give you something like: %userprofile%\AppData\Local\Packages<productname>\LocalState. This ensures you being able to read/write from/to files.
  • Fill the List with actual data so you can differentiate between a saved list and the default list.

Edit 1:
I just replicated your Code and made some adjustments to it. It's not perfect but it definately worked for me.

StateData:

using System;

[Serializable]
public struct StateData
{
    public string m_Name;
    public string m_Location;
    public string m_GameText;

    public StateData(string name, string location, string gameText)
    {
        m_Name = name;
        m_Location = location;
        m_GameText = gameText;
    }
}

StateDataCollection:

using System;
using System.Collections.Generic;

[Serializable]
public class StateDataCollection
{
    public List<StateData> m_StateData;

    public StateDataCollection() => m_StateData = new List<StateData>();
}

JSONReader:

using System.IO;
using UnityEngine;

public class JSONReader : MonoBehaviour
{
    private const string FILENAME = "StateData.json";

    private string m_path;
    public string FilePath {
        get => m_path;
        set => m_path = value;
    }

    void Start()
    {
        FilePath = Path.Combine(Application.persistentDataPath, FILENAME);
        Debug.Log(FilePath);// delete me

        StateDataCollection stateDataCollection = new StateDataCollection();
        stateDataCollection.m_StateData.Add(new StateData("Peter", "X", "123"));
        stateDataCollection.m_StateData.Add(new StateData("Annie", "Y", "42"));
        stateDataCollection.m_StateData.Add(new StateData("TheGuyFromTheSupermarket", "Supermarket", "666"));


        SaveStateDataCollectionToPath(FilePath, stateDataCollection);

        LoadStateDataCollectionFromPath(FilePath);
    }

    private void SaveStateDataCollectionToPath(string path, StateDataCollection stateDataCollection)
    {
        // ToDo: some checks on path and stateDataCollection
        string json = JsonUtility.ToJson(stateDataCollection, true);// prettyPrint active

        File.WriteAllText(path, json);
    }

    private void LoadStateDataCollectionFromPath(string path)
    {
        if(File.Exists(path)) {
            Debug.Log($"File exists at: {path}");// delete me

            string json = File.ReadAllText(path);
            StateDataCollection stateDataCollection = JsonUtility.FromJson<StateDataCollection>(json);

            // delete me
            Debug.Log($"StateDataCollection count: { stateDataCollection.m_StateData.Count}");
            int i = 1;
            stateDataCollection.m_StateData.ForEach(o => {
                Debug.Log(
                    $"Item Nr.: {i}\n" +
                    $"Name: {o.m_Name}\n" +
                    $"Location: {o.m_Location}\n" +
                    $"GameText: {o.m_GameText}\n\n");
                ++i;
            });
        }
    }
}

I also added a few Debug.Log()s for testing.
Usage:
Run it once with SaveStateDataCollectionToPath(FilePath, stateDataCollection); active and once without it. The Console should display 3 items.
Edit 2:
I think your issue might have been naming-convention violation. File requires using System.IO;, which beside File also contains Path. Unfortunately you also named your const string "Path".

ge.go
  • 65
  • 1
  • 10
  • Hey ge.go, thanks a lot for the reply. You helped me find out what what wrong. I used the output file as a basis to build my JSON text and then it worked. Apparently there was something wrong with the formatting but the rest I left unchanged. All the commas, bracers, parenthesis, etc were in place. Only the indentation was different which does not seem to be a cause for error but it works. TY forthe help! – Ken Pino Oct 06 '20 at 03:50