Save a game scene to file at runtime with many dynamically instanced gameObjects in and textures
I've created an RPG with lots of dynamically instanced character game objects in, each with randomly generated names and textures, they even have dynamically generated sprite icons rendered from a camera as texture2d and saved as sprites in their root game object. Each character has a lot of stats and clothes/weapon/items each with their own meshes reference on the character.
Now I need to save the scene. I've built a save/load UI but after looking at many serialization tutorials none appear simple. The stock serialization to file unity tutorial doesn't even talk about serializing unity types and instead just talks about simple types.
I have put all my character and item references into a single script container.... how do I save the scene and reload it at runtime with all my characters , stats, items, textures and positions in place.
I hope it would be something simple like Application.saveScene(filename).... but alas no.
It won't be a easy one line solution. You'll need to write all of the data to a file, then during load, instantiate all of the needed objects and set their data.
Say you have 3 NPC,s each with a unique name. You'll write in a file that there are 3 npcs with those names. Then during load, you'll see that there was 3 NPCs, so you'll need to instantiate the 3 NPCs and set their names.
Unity asset store has many serialization/deserialization or file io solutions which will simplify the task. I prefer json, but it's up to your preference, there's nothing wrong with using xml, binary or whatever. Just some assets do things a bit differently, some are easier to understand while some are more complex to understand. I would suggest browsing around and see what they have to offer.
I know its hard because I've spent the last week or so looking for a solution but the thing is I don't really know why it is so hard. I understand in some specific circumstances you may care about the memory size of the save game and so you perhaps wouldn't want to save everything including the scene objects... but for a simple blanket solution why can't you save the entire scenestate ?
It would make sense to save every gameobject at a particular time in a scene? Then to load it you'd just load the entire scene in the same way that unity saves and loads scene files and the objects in them at loadtime.
In your example about the 3 npcs why wouldn't the instances be saved completely with all their names and other parameters intact?
Hello, I have the same problem you originally had and I was wondering if you found a solution? Anything simple Unity offers which would solve it? Thanks
Hi. I need same save scene solution. Anyone knows something good?
Answer by D3mon1zA · Sep 08, 2016 at 09:57 AM
it is alot easier than what it seems, bear with me it is a bit long, I hope this helps.
first step:
using.UnityEngine;
using.System;
using.System.IO;
using.System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
next declare all your variables (I have mine as public, as this is the core for my character):
DateTime now = DateTime.Now;
string format = "dd MM yyyy hh:mm";
string loadDate;
string saveDate;
public int Level = 1;
public int currentXP = 0;
public int toNxtLvl = 500;
public int health = 5;
public int strength = 1;
public int stanima = 1;
public int agility = 1;
Vector3 playerPos;
public static _GameControl control; //with this you can acces the variables in this class from another //script by going _GameControl.control.health;
now you need to put in this to ensure that the data in this script is stored between scenes and so you cant accidently spawn 2 of this class ( so if you change scene the original will change scene with you and will remove any copys in the new scene) to do that you need this:
void Awake()
{
if (control == null)
{
DontDestroyOnLoad(gameObject);
control = this;
}
else if(control != null)
{
Destroy(gameObject);
}
}
now you need a new class that can serialise your data which looks like this:
[System.Serializable]
class playerData
{
public int level;
public int curXp;
public int toNxt;
public int health;
public int strength;
public int stanima;
public int agility;
public Vector3 pPos;
//these all need to be public so you can access them through save and load }
now you need a Save Function:
void Save()
{
playerPos = GameObject.Find("Player").transform.position;
saveDate = (now.ToString(format));
BinaryFormatter binary = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath +"/SaveGame.dat"); //the creates a file in the unity app data path
playerData dat = new playerData();
dat.level = Level; //this transfers the data you want to your serializable class
dat.curXp = currentXP;
dat.toNxt = toNxtLvl;
dat.health = health;
dat.strength = strength;
dat.stanima = stanima;
dat.agility = agility;
dat.pPos = playerPos;
binary.Serialize(file, dat);
file.Close();
and finally the load function which is pretty much the same as the save but kinda reversed:
void Load()
{
if (File.Exists(Application.persistentDataPath + "/SaveGame.dat"))
{
BinaryFormatter binary = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/SaveGame.dat", FileMode.Open);
playerData dat = (playerData)binary.Deserialize(file);
file.Close();
Level = dat.level; //this sets all the saved data back onto your character or npc's
currentXP = dat.curXp;
toNxtLvl = dat.toNxt;
health = dat.health;
strength = dat.strength;
stanima = dat.stanima;
agility = dat.agility;
playerPos = dat.pPos;
}
}
https://www.youtube.com/watch?v=yxziv4ISfys This video explains this alot better than I have haha
They're asking for a way to save the entire scene, not just the playerdata, but that does help a bit.
Your answer
