What is binaryformatter and how to use it? And how to use filestream?
What is binaryformatter and where can I find a very simple example about it? Same with filestream.
Answer by Commoble · Mar 01, 2017 at 09:05 PM
BinaryFormatter is used to serialize an object (meaning it converts it to one long stream of 1s and 0s), and deserialize it (converting that stream back to its usual form with all data intact), and is typically used with to save data to the hard disk so it can be loaded again after the game is closed and started up again.
There's a good tutorial here that goes over using BinaryFormatter and FileStream to save and load data, but it's a bit long.
As for simpler examples, these are bits of my own SaveManager class I ended up with after watching that tutorial:
public class SaveManager
{
private SaveGlob saveGlob; // the Dictionary used to save and load data to/from disk
protected string savePath;
public SaveManager()
{
this.savePath = Application.persistentDataPath + "/save.dat";
this.saveGlob = new SaveGlob();
this.loadDataFromDisk();
}
/**
* Saves the save data to the disk
*/
public void saveDataToDisk()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(savePath);
bf.Serialize(file, saveGlob);
file.Close();
}
/**
* Loads the save data from the disk
*/
public void loadDataFromDisk()
{
if(File.Exists(savePath))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(savePath, FileMode.Open);
this.saveGlob = (SaveGlob)bf.Deserialize(file);
file.Close();
}
}
where SaveGlob is a class with the [System.Serializable] attribute that holds whatever data you need to save. It could conceivably look as simple as this, or it could hold entire arrays or even dictionaries of data:
[System.Serializable]
public class SaveGlob
{
public int level;
public float health;
public bool isHardMode;
}
How could i call your function loadDataFromDisk() from javascript? reason i ask is my main menu is written in javascript and it can't access this because this isn't in the scene.
@J-R-Wood Answering your question as this might be looked up by others. You can access it from javascript by simply adding a static state to the functions. You will need to work a bit on the setup of your project (if you have not yet) to allow static data to be loaded into the scenes properly, but it's generally about having one master script that hold all the data loaded by the Load functions and, as well, having the the Save functions taking from that master script into the data being formatted into binary. Such script is usually on an object and has the "DontDestroyOnLoad(this.gameObject)" call in its awake method so that the data can be kept between each scene being loaded.
I'll add an useful tip: You can create more than one save files, but can't load binary formatted data without the same "content". For example, if you change the SaveGlob class in the example by adding a new parameter (like a public int currency) after releasing the game, every players who previously played the game would have the game hard-crash on them as the updated binary formatting will look for a binary list that is incomplete and the only fix is to forcefully delete the previous save or create some multiple-layered load that converts old save to new ones. Such trick ends up being pretty much a data blander which might raise the save loading time (or the impact on the CPU) when you reaches a state where you had dozen of updates to the saves file content. It's extremely frustrating and easy to break, hence it's sometimes better to just add a new serializable class with the additional values to be stored on a separate file (hence having multiple save function with BinaryFormatter.) Then, as the player load the saved file, the game loads the "old" file fine and can create a new file for the content added by the recent patch.