ShulkTNT2
ShulkTNT2

Reputation: 11

Loading Multiple Objects as GameObjects from Json In Unity 3d

I am trying to implement a simple Save/Load System using JSON in my Unity Project, however have run into multiple Issues. Any help?

public void SaveToJson(string ObjectName, float trfx, float trfy, float trfz, float rotx, float roty, float rotz)
    {
        objectData data = new objectData();
        data.name = ObjectName;
        data.trfx = trfx;
        data.trfy = trfy;
        data.trfz = trfz;
        data.rotx = rotx;
        data.roty = roty;
        data.rotz = rotz;

        string json = JsonUtility.ToJson(data, true);
        File.WriteAllText(Application.dataPath+"/ObjectDataFile.json", json);
    }

    public void LoadFromJson()
    {
        string json = File.ReadAllText(Application.dataPath+"/ObjectDataFile.json");
        // objectData data = JsonUtility.FromJson<objectData>(json);
        foreach(objectData data in JsonUtility.FromJson<objectData>(json))
        {
            Vector3 transformData = new Vector3(data.trfx, data.trfy, data.trfz);
            Vector3 rotationData = new Vector3(data.rotx, data.roty, data.rotz);
            Instantiate(GameObject.Find(data.name), transformData, Quaternion.Euler(rotationData));
        }
    }

One error it returns is this: "SaveObjectToJson.cs(39,36): error CS1579: foreach statement cannot operate on variables of type 'objectData' because 'objectData' does not contain a public instance or extension definition for 'GetEnumerator'"

I tried appending each object to a Json file everytime it is created, however get thrown errors. Also because of this, I do not know if it actually appends data or rewrites the entire file.

Upvotes: 1

Views: 178

Answers (1)

Ilya
Ilya

Reputation: 26

There are a few issues at play here, I will try my best to explain.

  1. It seems like you are trying to save a single item but load it in as a List - hence the GetEnumerator error
  2. The JsonUtility will not work with serializing a list and you will need to create a container object. This should exapling it -> (How to save List with help of JSON?)

Also if you're serializing you dont need to deconstruct the position and rotation to individual floats you can serialize those types directly

I made a quick editor script so I can test that the below code is working properly and should hopefully solve your problem (feel free to remove editor and testing parts). I hope this works for you and let me know if you have any more question

using System;
using System.Collections.Generic;
using System.IO;
using Unity.Plastic.Newtonsoft.Json;
using UnityEditor;
using UnityEngine;

public class Testing
{
    [MenuItem("Testing/SaveJson")]
    public static void SaveToJsonTest()
    {
        string json = JsonUtility.ToJson(CreateDummyData(), true);
        File.WriteAllText(Application.dataPath + "/ObjectDataFile.json", json);
    }

    public void SaveToJson(List<objectData> data)
    {
        string json = JsonUtility.ToJson(data, true);
        File.WriteAllText(Application.dataPath + "/ObjectDataFile.json", json);
    }

    [MenuItem("Testing/LoadFromJson")]
    public static void LoadFromJson()
    {
        string json = File.ReadAllText(Application.dataPath + "/ObjectDataFile.json");
        ObjectDataCollection objDataCollection = JsonUtility.FromJson<ObjectDataCollection>(json);

        foreach (var objectData in objDataCollection.Data)
        {
            Debug.Log($"Name: {objectData.name} | Position: {objectData.Pos} | Rotation: {objectData.Rot}");
        }
    }

    private static ObjectDataCollection CreateDummyData()
    {
        List<objectData> data = new List<objectData>();

        data.Add(new objectData("Cube", new Vector3(1, 2, 3), new Vector3(4, 5, 6)));
        data.Add(new objectData("Sphere", new Vector3(7, 8, 9), new Vector3(10, 11, 12)));

        ObjectDataCollection collection = new ObjectDataCollection();
        collection.Data = data;

        return collection;
    }
}

[Serializable]
public class ObjectDataCollection
{
    public List<objectData> Data;
}

[Serializable]
public class objectData
{
    [JsonProperty]
    public Vector3 Pos;

    [JsonProperty]
    public Vector3 Rot;

    public string name;

    public objectData()
    {
    }

    public objectData(string name, Vector3 Pos, Vector3 Rot)
    {
        this.name = name;
        this.Pos = Pos;
        this.Rot = Rot;
    }
}

Upvotes: 0

Related Questions