Unable to load Json to an object array
Basically when the save function is called it only seems to save the InsanceIds to the json file please see attached save.txt file (maybe on a separate post due to upload limit). alt text when I do a Debug.Log, if I type just wrap I just get a JobManagerWrapper object, if I type wrap.array then I get JobManager[], if I type wrap.array[0] then I get Job1[jobManager]
Please see attached screenshots for breakpoints results from the save.alt text (have to put the 2nd in a separate post as it wont allow me to add anymore attachments).
On Loading its passed all the instanceIDs that are in the save.txt, when I do a Debug.Log(j.array[0].jobStatus)) it's set to 0 and it should be 1 as in the save before that's what it was set to.
public static void Save()
{
JobManagerWrapper wrap = new JobManagerWrapper();
wrap.array = Resources.LoadAll<JobManager>("Jobs");
string jsonData = JsonUtility.ToJson(wrap);
File.WriteAllText(Application.persistentDataPath + "/save.txt", jsonData);
}
public static void Load()
{
if (FileCheck())
{
string jsonData = File.ReadAllText(Application.persistentDataPath + "/save.txt");
JobManagerWrapper j = JsonUtility.FromJson<JobManagerWrapper>(jsonData);
Debug.Log(jsonData);
}
else
{
Debug.LogError("Save file not found");
}
}
public class JobManagerWrapper
{
public JobManager[] array;
}
Thanks
So the problem is that the Job$$anonymous$$anager class is not being properly serialized since the Json file should contain other properties besides instanceID, like jobStatus. Correct? Could you also please post your current implementation of the Job$$anonymous$$anager class?
Well that's what i thought if you drill down enough you get the details the example would be Debug.Log(j.array[0].jobStatus)) does give you the information.
Here's the Job $$anonymous$$anager code
[CreateAsset$$anonymous$$enu(fileName = "Job", menuName = "Jobs")]
[Serializable]
public class Job$$anonymous$$anager : ScriptableObject {
public int jobNumber;
public int jobStatus;
void Awake()
{
SaveLoad$$anonymous$$anager.Load();
}
}
Hi $$anonymous$$acDx
Is there any further information I can provide you? I have been unsuccessful in getting this working
Thanks
Answer by MacDx · May 18, 2018 at 10:06 PM
Ok after testing and researching this topic myself it looks like the problem is Unity's serialization ways, when you serialize a single object it gives the correct output because it has to look into the contents of the object. However, when you pass it an object with an array of references, like in your case, Unity says, these are references to Objects (Unity's own object type that contains instanceID) so it will be better if I save the ID from this instead since you can fetch it by ID later (this is my guess).
So the options I can come up with for you are:
1) Once again, switch to Json .NET or any other json library, just stop using JsonUtility.
2) Create a proxy object which is a plain C# class that has the same properties as the scriptable object and change the wrapper class to use those instead in the array. Then have a method on your scriptable object that returns an fresh instance of the proxy type with it's properties already set, so when you get the array of JobManagers using Resources.LoadAll you can call that method and populate the wrapper's array more easily.
Regards
Note: Also stop calling Load in the scriptable object's Awake method, it is a bad idea to do so. Use a button or some monobehaviour's awake/start instead.
Hi $$anonymous$$acDx
Sorry for the late response I've been really busy, can you confirm what you mean by a Proxy Object? or show me how its implemented.
I will not load from the Awake() as I said it was a temporary measure.
Thanks
Hi $$anonymous$$acDx
I have been Debugging the code further and found there is an error which is why its not working, here's the error:
"ArgumentException: JSON must represent an object type. UnityEngine.JsonUtility.FromJson[Job$$anonymous$$anagerWrapper] (System.String json) (at C:/buildslave/unity/build/artifacts/generated/common/modules/JSONSerialize/JsonUtilityBindings.gen.cs:25) SaveLoad$$anonymous$$anager.Load () (at Assets/Scripts/SaveLoad$$anonymous$$anager.cs:63) JobSearch.Start () (at Assets/Scripts/JobSearch.cs:24)"
the above seems to happen when this line of code executes
Job$$anonymous$$anagerWrapper j = JsonUtility.FromJson<Job$$anonymous$$anagerWrapper>(jsonData);
hope this helps
Hi $$anonymous$$acDx
I have been reading further online and this is my code so far however Jobs is always set to null.
public static Job$$anonymous$$anager[] Load()
{
if (FileCheck())
{
string jsonData = File.ReadAllText(Application.persistentDataPath + "/save.txt");
Debug.Log(JsonHelper.FromJson<Job$$anonymous$$anager>(jsonData));
Job$$anonymous$$anager[] jobs = JsonHelper.FromJson<Job$$anonymous$$anager>(jsonData);
// Job$$anonymous$$anagerWrapper j = JsonUtility.FromJson<Job$$anonymous$$anagerWrapper>(jsonData);
return jobs;
}
else
{
Debug.LogError("Save file not found");
return null;
}
}
}
public static class JsonHelper
{
public static T[] FromJson<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.Items;
}
[Serializable]
private class Wrapper<T>
{
public T[] Items;
}
}
This was my source of information here.
Thanks and apologies for the post overload I just really want to get this sorted.
Your answer
Follow this Question
Related Questions
Calling an array 1 Answer
JSON weird deserialization 1 Answer
Storing levels data as json? 0 Answers
Serialization of ScriptableObject not hexadecimal (json) 1 Answer