HELP Binary save system

PLEASE someone to give me a code or help me!!!
Since 2 weeks I am trying different Binary systems from youtube tutorials and no one works for me :frowning:

Here is the last one:

SaveSystem

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

public class SaveSystem : MonoBehaviour
{
#region Instance
    private static SaveSystem instance;

    public static SaveSystem Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<SaveSystem>();
                if (instance == null)
                {
                    instance = FindObjectOfType<SaveSystem>();

                    instance = new GameObject("Spawned SaveSystem", typeof(SaveSystem)).GetComponent<SaveSystem>();
                }
            }

            return instance;
        }

        set
        {
            instance = value;
        }
    }




    #endregion
   
    [Header("Logic")]
    [SerializeField] private string savefileName = "saves.s";

    private PlayerData data;
    public  PlayerData Data { get => data; set => data = value; }
    private BinaryFormatter formatter;

    void Awake ()
    {
        formatter = new BinaryFormatter();
        DontDestroyOnLoad(this.gameObject);
    }

public void SaveData()
    {
        if (Data == null)
        {
            Data = new PlayerData();


            var file = new FileStream(savefileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

            formatter.Serialize(file, Data);
            file.Close();
         
            Debug.Log("Data Saved");
           
        }

    }

    public void LoadData()
    {
        try
        {
            var file = new FileStream(savefileName, FileMode.Open, FileAccess.Read);
            Data = (PlayerData)formatter.Deserialize(file);
            file.Close();

            Debug.Log("Data Loaded");
       
        }
        catch
        {
            Debug.LogError("Save file not found in " + savefileName);
            SaveData();
        }
 
    }
}

The data that I want to save and load:

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

[System.Serializable]
public class PlayerData
{
    public float coins { set; get; }
    public  bool isLaserBought { set; get; }
}

P.S. I want to be able to ‘‘interact’ with the data’ to get and set it

What is it that “doesn’t work” about it? What happens when you try to save it?

1 Like

I would highly recommend something human readable like JSON to make your save system. It’s 10x easier to debug issues because you can just open the file and see at a glance what’s being written to the file. With binary saves you have to pull out a hex editor to tell what’s going on and even then it’s really easy to miss things :face_with_spiral_eyes:

3 Likes

When I try to add value to the coins variable
5818435--616423--upload_2020-5-8_0-23-3.png

i get 5818435--616426--upload_2020-5-8_0-25-30.png

The error happens in a script called GameManagerScript, which you haven’t posted. What is going on around line 51 of GameManagerScript.cs?

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManagerScript : MonoBehaviour
{
    public AudioSource inGame;
    public DataMono dataMono;
   
 
    public GameObject playerObject;
    public SaveSystem saveSystem;
    public static PlayerMovement movement;
 

    public GameObject DieUi;
    [SerializeField]
    public static bool isGameEnded;
    public bool gameAlreadyEnded;
    void Awake ()
    {
     // var saveSystem = SaveSystem.Instance;
      
  

        gameAlreadyEnded = false;
        movement = playerObject.GetComponent<PlayerMovement>();
        isGameEnded = false;
        movement.enabled = false;
    }

    void Update()
    {
     //   var saveSystem = SaveSystem.Instance;
        if (isGameEnded == true)
        {
            if(gameAlreadyEnded == false)
            {
              
            EndGame();
                gameAlreadyEnded = true;
            }
        }
    }

    public void EndGame()
    {

           var saveSystem = SaveSystem.Instance;
       
        saveSystem.Data.coins += 2f;
        //SaveSystem.Instance.Data.isLaserBought = true;

        saveSystem.SaveData();
        saveSystem.LoadData();
        Debug.Log(saveSystem.Data.coins);
        inGame.Stop();
        Debug.Log("END GAME");
        movement.enabled = false;
 
       
   Invoke("LoadDieUi", 1.5f);
     
    }
 
    void LoadDieUi ()
    {
        DieUi.SetActive(true);
    }
 
}

You try and access saveSystem.Data before you save or load it, so saveSystem.Data is null. Maybe you should be calling saveSystem.LoadData in GameManagerScript’s Awake or Start?

I tried like that

        saveSystem.LoadData();

        saveSystem.Data.coins += 2f;
        saveSystem.SaveData();
        Debug.Log(saveSystem.Data.coins);

but it doesn’t really save and increase the coins

Please someone :frowning:

no one use binary ?

You’re not doing yourself any favors with how little information you are providing. You say you ran the above and it “doesn’t really save”. Well what does it “really” do specifically? LoadData has Debug lines, so which one was output to the console?

1 Like

You complicated it too much for yourself by having everything in different scripts.

If you are just starting to learn try saving a simple file with methods and classes all from the same script

The coins that I am increasing doesn’t save. I know that because the Debug.Log always show the same amount of coins.

I am doing it with tutorials exactly the same as the video. No one works

try this code and let me know

put it in a new script called savetest

you can just use the inspector to mess around with it

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

public class savetest : MonoBehaviour
{
    public BinaryFormatter bf = new BinaryFormatter();
    public FileStream fs;

    public int Coins;
    public bool TriggerSave;
    public bool TriggerLoad;

    [Serializable]
    public class SaveClass
    {
        public int Save_Coins;
    }

    public void SaveMethod()
    {

        if (Directory.Exists(Application.dataPath + "/Save/") == false)
        {
            Debug.Log("creating dir");
            Directory.CreateDirectory(Application.dataPath + "/Save/");
        }

        fs = File.Create(Application.dataPath + "/Save/saved.coins");

        sv = new SaveClass();
        sv.Save_Coins = Coins;
        bf.Serialize(fs, sv);

        fs.Close();
    
    }


    public void LoadMethod()
    {

        if (File.Exists(Application.dataPath + "/Save/saved.coins") == true)
        {

            fs = File.Open(Application.dataPath + "/Save/saved.coins", FileMode.Open);
            sv = (SaveClass)bf.Deserialize(fs);
            Coins = sv.Save_Coins;
            fs.Close();


        }


    }

    void Update()
    {

        if (TriggerSave == true)
        {
            SaveMethod();
            TriggerSave = false;
        }
        if (TriggerLoad == true)
        {
            LoadMethod();
            TriggerLoad = false;
        }
    }

}

Thank you for the reply. I get an error error CS0103: The name ‘sv’ does not exist in the current context

1 Like

sorry forgot this, replace the code with this

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    using UnityEngine;
    
    public class savetest : MonoBehaviour
    {
        public BinaryFormatter bf = new BinaryFormatter();
        public FileStream fs;
        public SaveClass sv;
    
        public int Coins;
        public bool TriggerSave;
        public bool TriggerLoad;
    
        [Serializable]
        public class SaveClass
        {
            public int Save_Coins;
        }
    
        public void SaveMethod()
        {
    
            if (Directory.Exists(Application.dataPath + "/Save/") == false)
            {
                Debug.Log("creating dir");
                Directory.CreateDirectory(Application.dataPath + "/Save/");
            }
    
            fs = File.Create(Application.dataPath + "/Save/saved.coins");
    
            sv = new SaveClass();
            sv.Save_Coins = Coins;
            bf.Serialize(fs, sv);
    
            fs.Close();
      
        }
    
    
        public void LoadMethod()
        {
    
            if (File.Exists(Application.dataPath + "/Save/saved.coins") == true)
            {
    
                fs = File.Open(Application.dataPath + "/Save/saved.coins", FileMode.Open);
                sv = (SaveClass)bf.Deserialize(fs);
                Coins = sv.Save_Coins;
                fs.Close();
    
    
            }
    
    
        }
    
        void Update()
        {
    
            if (TriggerSave == true)
            {
                SaveMethod();
                TriggerSave = false;
            }
            if (TriggerLoad == true)
            {
                LoadMethod();
                TriggerLoad = false;
            }
        }
    
    }
1 Like

Awesome, it works! But I have 2 questions.

  1. How can I add more variables to save like: public bool isLaserBought ?
  2. Why you are using TriggerLoad and TriggerSave when you can call the methods directly?
  1. add them in your declarations and in the save class
public bool LaserBought;
[Serializable]
        public class SaveClass
        {
            public int Save_Coins;
public bool Save_LaserBought;
        }

dont forget that you have to include them in the save and load part like this

 sv = new SaveClass();
            sv.Save_Coins = Coins;
            sv.Save_LaserBought = LaserBought;
            bf.Serialize(fs, sv);
  
            fs.Close();
                sv = (SaveClass)bf.Deserialize(fs);
                Coins = sv.Save_Coins;
                LaserBought = sv.Save_LaserBought;
                fs.Close();
  1. I made those triggers so you could click the bools on the inspector to help you learn how it works