简体   繁体   中英

C# Unity Reading data from JSON into an Object Array

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!

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".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM