Saving data with files

So i followed the tutorials on how to use FileStream and binary formatter and came up with the code below, my issue is saving and loading from another C# script…

what I want it to do:

  1. all setting are stored under a C# script called. GameData (all are public static ints)

  2. the SaveLoad script will take the GameData script and store everything in a binary file

  3. then when the program starts it will call the GameData binary file and write i into the GameData C# script
    .

    using System.Collections;
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;

    public class SaveLoad : MonoBehaviour
    {

    public static void Save()
    {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream stream = new FileStream(Application.persistentDataPath + "/GameData.dat", FileMode.Create);
    
        GameData data = new GameData();
    
        bf.Serialize(stream, data);
        stream.Close();
    }
    
    public void Awake()
    {
        if(File.Exists(Application.persistentDataPath + "/GameData.dat"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream stream = new FileStream(Application.persistentDataPath + "/GameData.dat", FileMode.Open);
    
            GameData data = bf.Deserialize(stream) as GameData;
    
            stream.Close();
        }
        else
        {
            Debug.Log("GameData.dat not found!");
        }
    }
    

    }

and the GameData Look like this:

.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class GameData {

    public int musicVolume;
    public int gameVolume;
    public int firstPlay;
    public int mapSize;
    public int coins;

}

I’ve tried everything i can think of and look around but couldn’t find anything how can i do this or is it possible?

There is several wrong / strange with your code. First of all you initially had your variables static. Though as Hellium said static variables are not serialized as they do not belong to an instance of the class.

Inside your Save method you create a new instance of your “GameData” class which you serialize and write to disk. However you never set any of the fields of that class. When you create a new instance of the class all variables will get their default values of “0”.

 GameData data = new GameData(); // new instance of "GameData"
 bf.Serialize(stream, data);  // serializing that new instance to disk.

Likewise when you’re deserializing your data you correctly recreate the class instance from the serialized information and store it in the local “data” variable. However you don’t do anything with that data after deserialization. The local variable is only valid inside your Awake method.

Since you initially had the variables static you probably accessed them from several other scripts directly. Of course this doesn’t work when you have an instance of a class. The easiest solution is to use a simple singleton. Change your GameData class to:

[System.Serializable]
public class GameData
{
    public static GameData Instance = new GameData();
    
    public int musicVolume;
    public int gameVolume;
    public int firstPlay;
    public int mapSize;
    public int coins;
}

That way you actually have a single instance of your class stored in a static variable. Now instead of doing GameData.musicVolume you would do GameData.Instance.musicVolume.

Now when serializing the data you don’t want to create a new empty class since it won’t contain any data. Instead just serialize our singleton instance:

bf.Serialize(stream, GameData.Instance); 

And when deserializing you just replace the old singleton with the new one:

GameData.Instance = (GameData)bf.Deserialize(stream);

Also generally avoid using an “as” cast if you do not perform a null check afterwards. An as cast can hide / delay problems and just makes it harder to debug. A normal cast will throw an exception if the cast fails and gives you a proper error message what went wrong.

any Ideas?