- Home /
Saving your scene and location in game?
Im working on a level based game in which a player goes therough long unique levels to get to a point in the game and loads up another scene. It would be nice to have a save system so when youcexit out or when the game crashes, it will know your location and the scene your on. I have seen someone save the gems they have collected to keep track of where they were. But i would like it so it auto saves every minute for a location and scene. I suppose it would be easier to only do scene so it would be cool if someone could help me do it both ways. I would also love it if i can have bakup save files in case the game is deleted and put those bakups in lets say programs 86 or appdata. If anyone could help me with that it would come in handy in a lot of things so i can learn to access a users files to give them hints. Im sure im not the only one wanting to learn this. I cant watch videos fyi lol.
Answer by Cherno · May 16, 2015 at 05:25 AM
You can use a BinaryFormatter to serialize and save a class instance to file.
First, We need a class that holds all the data that you want to save.
using UnityEngine;
using System.Collections;
[System.Serializable]//Important! Every custom class that needs to be serialized has to be marked like this!
public class Game { //don't need ": Monobehaviour" because we are not attaching it to a game object
public string savegameName;//used as the file name when saving as well as for loading a specific savegame
public string testString;//just a test variable of data we want to keep
}
Now, we need the actual functions that save and load a Game instance.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad {
//it's static so we can call it from anywhere
public static void Save(Game saveGame) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create ("C:/Savegames/" + saveGame.savegameName + ".sav"); //you can call it anything you want, including the extension. The directories have to exist though.
bf.Serialize(file, saveGame);
file.Close();
Debug.Log("Saved Game: " + saveGame.savegameName);
}
public static Game Load(string gameToLoad) {
if(File.Exists("C:/Savegames/" + gameToLoad + ".sav")) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open("C:/Savegames/" + gameToLoad + ".gd", FileMode.Open);
Game loadedGame = (Game)bf.Deserialize(file);
file.Close();
Debug.Log("Loaded Game: " + loadedGame.savegameName);
}
else {
Debug.Log("File doesn't exist!");
return null;
}
}
}
For testing purposes, use a simple script attached to a gameobject that call the save and load functions.
using UnityEngine;
using System.Collection;
public class SaveLoadMenu : MonoBehaviour {
public string text = "";//the string we want to save and load. Corresponds to Game.testString
private string saveGameName = "My Saved Game";//The name of our saved game to save and load.
void OnGUI () {
saveGameName = GUI.TextArea(new Rect(20, 0, 50, 200), saveGameName);
text = GUI.TextArea(new Rect(20, 50, 50, 200), text);
if(GUI.Button(new Rect(20, 100, 50 150), "Save")){
Game newSaveGame = new Game();
newSaveGame.saveGameName = saveGameName;
newSaveGame.testString = text;
SaveLoad.Save(newSaveGame);
}
if(GUI.Button(new Rect(20, 150, 50, 150), "Load")){
Game loadedGame = SaveLoad.Load (saveGameName);
if(loadedGame != null) {
text = loadedGame.testString;
}
}
}
}
Im about to test it out, i strongly apretiate all the work you put into this, thanks alot bro.
Edit: it dosnt recognize loadedGame, it says it does not exist in this current context.
$$anonymous$$ost, if not all, Unity-specific classes like Vector3, Color, Transform etc. are not marked as serializable and wil throw an aerror when trying to do so.
If you want to save a such a variable, like a Vector3, you either have to use three seperate floats to save the xyz values, which can be serialized without problems, or implement an ISerializationSurrogate, which tells the BinaryFormatter how to serialize a specific class.
$$anonymous$$ore information here:
Run-time Serialization, Part 3
using System.Runtime.Serialization;
using UnityEngine;
sealed class Vector3SerializationSurrogate : ISerializationSurrogate {
// $$anonymous$$ethod called to serialize a Vector3 object
public void GetObjectData(System.Object obj,
SerializationInfo info, Strea$$anonymous$$gContext context) {
Vector3 v3 = (Vector3) obj;
info.AddValue("x", v3.x);
info.AddValue("y", v3.y);
info.AddValue("z", v3.z);
//Debug.Log(v3);
}
// $$anonymous$$ethod called to deserialize a Vector3 object
public System.Object SetObjectData(System.Object obj,
SerializationInfo info, Strea$$anonymous$$gContext context,
ISurrogateSelector selector) {
Vector3 v3 = (Vector3) obj;
v3.x = (float)info.GetValue("x", typeof(float));
v3.y = (float)info.GetValue("y", typeof(float));
v3.z = (float)info.GetValue("z", typeof(float));
obj = v3;
return obj; // Formatters ignore this return value //Seems to have been fixed!
}
}
In the Save function, before creating a new File, the ISS has to be added to the BF:
using System.Runtime.Serialization.Formatters.Binary;
public static void Save(Game saveGame) {
BinaryFormatter bf = new BinaryFormatter();
// 1. Construct a SurrogateSelector object
SurrogateSelector ss = new SurrogateSelector();
Vector3SerializationSurrogate v3ss = new Vector3SerializationSurrogate();
ss.AddSurrogate(typeof(Vector3),
new Strea$$anonymous$$gContext(Strea$$anonymous$$gContextStates.All),
v3ss);
// 2. Have the formatter use our surrogate selector
bf.SurrogateSelector = ss;
// FileStream file = File.Create etc...
Edit: it dosnt recognize loadedGame, it says it does not exist in this current context.
In the Load function (public static Game Load(string gameToLoad) {...)
change this line:
loadedGame = (Game)bf.Deserialize(file);
to
Game loadedGame = (Game)bf.Deserialize(file);
It's line 24 in the SaveLoad class I posted above.
Update: I have created a sample project that does basic GameObject serialization.
Your answer
Follow this Question
Related Questions
Creating a Save/Load game 2 Answers
How to load player last scene visited 1 Answer
Scene Saving 1 Answer
Saving/Loading variables 1 Answer
Not loading an object if it have be retained from a previous scene. 1 Answer