Search Unity

Question Getting exception link for my project included

Discussion in 'Scripting' started by SharonL75, Oct 4, 2020.

  1. SharonL75

    SharonL75

    Joined:
    Aug 13, 2020
    Posts:
    91
    This is the SaveLoad script :

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.IO;
    6. using System.Linq;
    7. using UnityEngine;
    8. using UnityEngine.UI;
    9.  
    10. public class SaveLoad : MonoBehaviour
    11. {
    12.    public List<Transform> objectsToSave = new List<Transform>();
    13.    public Button saveButton;
    14.  
    15.    private void Awake()
    16.    {
    17.        SaveSystem.Init();
    18.    }
    19.  
    20.    public void Save()
    21.    {
    22.        SaveGame saveGame = new SaveGame();
    23.        saveGame.saveObjects = new List<SaveObject>();
    24.        SaveObject saveObject = new SaveObject();
    25.        for (int i = 0; i < objectsToSave.Count; i++)
    26.        {
    27.            saveObject.gameObjectInstanceID = objectsToSave[i].gameObject.GetInstanceID();
    28.            var x = objectsToSave[i].GetComponents<Component>();
    29.            var stateQueryComponent = x.Where(component => component is IStateQuery).ToList();
    30.            List<KeyToValue> componentsState = new List<KeyToValue>();
    31.            foreach (var z in stateQueryComponent)
    32.            {
    33.                var w = z as IStateQuery;
    34.                componentsState.Add(new KeyToValue(w.UniqueId.ToString(), w.GetState()));
    35.            }
    36.  
    37.            saveObject.position = objectsToSave[i].position;
    38.            saveObject.rotation = objectsToSave[i].rotation;
    39.            saveObject.scaling = objectsToSave[i].localScale;
    40.  
    41.            saveObject.componentsState = componentsState;
    42.            saveGame.saveObjects.Add(saveObject);
    43.  
    44.            string json = JsonUtility.ToJson(saveObject);
    45.  
    46.            SaveSystem.Save(json);
    47.        }
    48.    }
    49.  
    50.    public void Load()
    51.    {
    52.        Dictionary<int, Transform> instanceIdToObject = objectsToSave
    53.            .ToDictionary(o => o.GetInstanceID(), o => o);
    54.        var saveString = SaveSystem.Load();
    55.        if (saveString != null)
    56.        {
    57.            SaveGame saveGame = JsonUtility.FromJson<SaveGame>(saveString);
    58.            foreach (var saveObject in saveGame.saveObjects)
    59.            {
    60.                List<KeyToValue> loadedComponents = saveObject.componentsState;
    61.                var objectToSetState = instanceIdToObject[saveObject.gameObjectInstanceID];
    62.  
    63.                objectToSetState.position = saveObject.position;
    64.                objectToSetState.rotation = saveObject.rotation;
    65.                objectToSetState.localScale = saveObject.scaling;
    66.  
    67.                var y = objectToSetState.GetComponents<Component>();
    68.                var z = y.Where(component => component is IStateQuery).ToList();
    69.                Dictionary<string, IStateQuery> zz = z.ToDictionary(sq => (sq as IStateQuery).UniqueId.ToString(), sq => sq as IStateQuery);
    70.  
    71.                foreach (KeyToValue keyvalue in loadedComponents)
    72.                {
    73.                    zz[keyvalue.Key].SetState(keyvalue.Value);
    74.                }
    75.            }
    76.        }
    77.    }
    78. }
    79.  
    The exception is on line 56 : When reading back from the text file to the json :

    Code (csharp):
    1.  
    2. SaveGame saveGame = JsonUtility.FromJson<SaveGame>(saveString);
    3.  
    This is how I'm saving the json to the file on the hard drive :

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.IO;
    6. using UnityEngine;
    7.  
    8. public static class SaveSystem
    9. {
    10.    private static readonly string SAVE_FOLDER = Application.dataPath + "/save_";
    11.    public static void Init()
    12.    {
    13.        if (!Directory.Exists(SAVE_FOLDER))
    14.        {
    15.            Directory.CreateDirectory(SAVE_FOLDER);
    16.        }
    17.    }
    18.  
    19.    public static void Save(string saveString)
    20.    {
    21.        string fileName = Path.Combine(SAVE_FOLDER, "savegame.txt");
    22.        File.AppendAllText(fileName, saveString);
    23.  
    24.    }
    25.  
    26.    public static string Load()
    27.    {
    28.        string fileName = Path.Combine(SAVE_FOLDER, "savegame.txt");
    29.        string content = File.ReadAllText(fileName);
    30.  
    31.        return content;
    32.    }
    33. }
    34.  
    I have two objects that I save it's info :



    I'm not sure why it's giving the exception error and how to resolve it. It happens when trying to load back the saved game not when saving.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    That's exactly your problem.

    It's expecting a single JSON object, but your file has two top-level JSON objects. It's happening because when you save your data, you're appending instead of overwriting. This
    Code (CSharp):
    1. File.AppendAllText(fileName, saveString);
    should be
    Code (CSharp):
    1. File.WriteAllText(fileName, saveString);
     
    Joe-Censored and SharonL75 like this.
  3. SharonL75

    SharonL75

    Joined:
    Aug 13, 2020
    Posts:
    91
    In the Save method in the SaveLoad script I'm doing :

    Code (csharp):
    1.  
    2. saveGame.saveObjects.Add(saveObject);
    3.  
    It's adding the saveObject to a List.

    But then in the Load using a break point on this line I see the saveObjects Listi s empty :

    Code (csharp):
    1.  
    2. foreach (var saveObject in saveGame.saveObjects)
    3.  
    Why it's empty on the load ?
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    I don't really have the time right now to read and understand all that code, but:
    Just wrap your objects in another object that has a list and serialize that:

    Code (CSharp):
    1. public class Wrapper {
    2.   public List<TypeThatINeedToSaveMultipleOf> Data;
    3. }