Saving Game Data in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody this is Gaines Plus James and welcome back to another yearly tutorial today we're gonna take a look at how to create a save system in unity now if you watch any tutorials on a channel where we've dealt with saving things before I'm the same in my udemy courses what we've used is the player pref system to save data which is a very very handy way to do saving which is really simple and really easy and it's ideal for learning the basics of saving and ideal for working on prototypes and things like that but when you expand out into doing a more fully featured game you will most likely want to have more control over what you're saving and how it's saving and you'll also want more control over the ability to delete those files maybe as players progress and to be able to have more flexibility in what's being saved because player press can only store in Toulouse flawed values are string values and obviously maybe want to have some more variety that you can store in your games so we're gonna take a look at how to create a save system and the same system we're gonna create here is almost exactly the same as what I use in my game scoop kaboom and the tomb of doom which you can see up on screen here now a little bit of footage of the game in action and don't forget that you can wish this the game on Steam there that really helps promote the game in steams kind of behind the scenes backend stuff and so if you can head to the link in the description down below and wish this the game that would be super P shares but now let's get on with this tutorial so I've got a very simple little level setup here if I hit this little button it blows up in the door we've reached a check point and we can select some stuff and we can respond so at the moment all the level does is if I hit these little spikes here it'll respawn me back at this checkpoint but if I stop the game and play again we go back to the start of level this button will be closed so we have to hit it to get back here and all this it'd be nice if we could respawn back at the checkpoint here another thing that would be nice is when you collect all these collectibles for example if I die in respawn now what you see in a lot of games is that those items will respawn we effectively reload the level so we'd really like that to happen so we'd like it to reload the level and pull from our saved data to tell us where to load it so let's stop this running here and the first thing we're going to do is create a script to manage our saves so I'm going to create an object here first of all that we'll use to represent it in the world so I'm gonna call this the save manager I'm gonna create a script a script in my scripts folder create a CGI script that will call save management I'm gonna attach that to the save manager object once it compiles let me try this again there we go I let's open this up so what we're going to use for this is something called XML serialization which will allow us to basically store information in a what's called an XML file but we can name it whatever we want it doesn't matter and that allows us to write some data into a file and then read it back out and do whatever we want along the way so to do that at the top here I'm going to use using system IO so system dot IO will allow us to save and load files to the computer that we're on then we're going to do using system - XML because we're using XML and I need to also use using system - XML serialization now there's a few different ways you can do what we're gonna do here we're using XML serialization you could also use binary formatting as well is another very common one but I found that this works very well for me so we're going to demonstrate this in action here so when we want to do this we need to make the type of data that we want to store so down the bottom here below our save manager class so after this final closing bracket here I'm gonna add in another public class that we're gonna call save data and then this is not gonna be a model behavior like we have up here this is just gonna be a normal class that I'm going to open and close the curly brackets here like this and then within here we're gonna put some variables that we would want to store so for example I'm gonna put in a string for the name of the save game that we're gonna say so I'm gonna call this save name I said I want to store where when our player hits a checkpoint and where they should respawn so let's create a public vector tree that will call respawn position I also want to do a couple of other things so if I jump back in here for example this button I want to save this button has been pressed I'm gonna save that and I also want to save how many lives our player has we'll do all these things one by one but we'll just set up the values in here for all of that as well so let's create a public pool here for door open like so and a public int for lives so you should see already that versus using player press we now have a few extra options available to us we can store a vector tree without having to separate it out into three different numbers and we can store a bool value without having to converse as to using for example 1 and 0 to represent if it's true or false so with that in mind then the other thing we need to do is go up here and we need to classify this script as system dot serializable so this means that this entire class will be serializable by the system and it means that first of all it allows to actually see these values in the inspector in unity and it also means that we will be able to save this information because we're using the serialization system up here so if I to save this first of all we can't see these values just by default because although they're in the same class script here I'm sorry during the same C sharp scripts they're not within this class so they don't appear down here we've essentially created another abstract class in here but what we can do is up the top here just create a public save dace oh I said save dace instead of save data that was a bit silly so there we go public save data that would call this will be our active save and this information here is what we're going to store so if I just save this jump back into unity we should see now we have this active save variable so I can collapse that down if I want to or if I open it up we can type in some information or we can use this to store this information so how do we store let's go back in here and what we're gonna do is create two functions I'm gonna create a public void save like so and a public void load like so oh I got all ahead of myself there oh it auto-completed something else for me there we go public void load there we go so in our save function here the first thing we're gonna need to know is where we want to actually save these files and the default place that most applications will save information is on to your system into a something called a persistent data path which is somewhere that stores all your files on your machine and how we can access that is we're gonna create a string here called data path and if I set that to be equal to application does persistent data path and this is a location on your machine that most games in general will save to and especially unity games will use this a lot and where this goes if I jump over into Chrome and look at the unity documentation for application dot persistent data path on a Windows machine it goes to the name of the user profile then updated local packages and then product name is whatever your actual product is and it'll save in here so any files you create will basically go to here and this also allows you to be able to whenever you want to manually go and delete any files you can just go to that directory and find us in there so we write two different places depending on different machines obviously but it's important just to note hey this will go to a particular place on our computer and then what we do next is write a particular bit of code that will handle this now this is just something that you don't necessarily need to memorize I certainly do not memorize this I basically just check this information whatever I need to create a save system what we do is we'll create a variable that we're going to call serializer and this is gonna be a new XML serializer there we go a new XML serialize what type of data we wanted to serialize so in here we say type of an in a bracket we wanted to serialize the save data that we created down here so we're gonna say serialize save data and we hit our semicolon at the end so we've got a serialize er created then we have to create a variable called stream which is gonna be a new file stream which is essentially a way of storing a new file in some memory and in here we're gonna say where we want this to go is to the data path that we just created up here then we're going to add on a forward slash to it so we're going inside this folder and then within here we're going to say that we're going to store the from the active SAV which is a reference to our safe data we're gonna get the save name that we want to use so active save save name so we're basically creating a document that for example let's say our save name let's go back into unity will just call our save name is save 1 so then what we're doing is saving as save 1 and let's give it a a extension to the end of it so we're gonna say save 1 - save it doesn't matter what you call this this could be literally anything probably not with semicolons in us but any series of letters it doesn't really matter we're gonna call it save and then we need to tell it that this is a we're in file mode - create because we're creating a file that we're going to save and then what we do is say with that stream that we just created we're gonna say we'll use the serializer that we had here tell that to serialize a file the file we want to sterilize is this stream we just created and what we want to put into that stream is our active save so in here we're gonna say active save so basically the important thing to make note of here the important thing to be aware of here is tree elements the type of information that you're saving the location of where you wanted to save so save name dot save is what we use in here and in here the actual object you want to save apart from that I personally reuse this same bit of code over and over and over again and just replace these values with whatever it is I want to serialize so finally once that is all done we can tell the stream to close and that will finish saving the file and we'll be done so I'm gonna add a little debug log here to tell me when a safe has been finished just so I know that it shows up in the machine so that's how we'll save so to then load we obviously want to do the opposite to that so what we're gonna do here is in the load section again we still need to know where our file is so we're gonna take this same data path string but then in here what we need to do is first of all check and see hey does this save actually exist if there is there any saved for us to load so here we're gonna say if and then we're going to say system dot IO again system that IO dot file exists so we're checking if a file exists and the file you want to check is this whole data path that we're using here so this the whole file name that we're setting up here I'm gonna pop that in there so check if that exists and if it does then we want to load it so we're gonna use a serializer and stream again so we're going to copy all of this information that we had previously pasted back in here but this time instead of creating a file we want to open a file and then in here instead of saying the serializer that's serialize the active save instead what we want to do is because we're loading we want to tell this active save to get the information out of this file so here we'll say active save equals serializer - d serialized so we use serializer dot serialized to set the information into place and in here we're going to deserialize it so we're taking it out we're taking it out of the stream and we just add that we're taking it out of the stream as save data so we're telling it this is the type of information that we're pulling out of this system and then once again we can tell that stream to close so stream - close like so and I'm gonna add another little debug here to say debug that log notice okay so that's perfect let's just add a quick little shortcut so we can say do these actions so I'm just gonna add a if input guess key down key code let's say K this will allow us to save that's just copy and paste this in here and then say key code L to load we go okay save that and let's go back into use down and just test this F so at the moment if I go and press play here and if I press my load key we should see that if I look down here I didn't get any message in the console I stopped is running look at a console we didn't get any message and that's because there was no file for us to load so if I try again here and if I press play and this time if I save first so hit okay there we go I got my save message in the bottom corner if I hit L I get my load of message so we know that at least that much is working but we don't know that we're actually saving some information and let's make this not maximize here what I'm gonna do is I'm going to play the game I'm gonna go here I'm gonna set my lives to be 5 and then I'm going to save I'm gonna stop this running no I don't decide it again stop running there we go and we should see now that our lives here are zero so we did save so if I play the game now we'll see okay there's still zero that's perfect but if I hit the L button there we go we get five popping up in our save manager so perfect that's working that's working the way we wanted to but of course that's all well and good that we're able to actively save and delete some are sorry save and load some files but we need to put that to some practical use and what we also would really like to do is be able to quickly delete those files to be able to check these things are working correctly as well so I'm gonna add another function public void Dilys save data and in here this is gonna be very very simple it's gonna take again the same string data pass in here and we're gonna again check and see if the file exists on to copy just copy this whole function of deletes the bits in the middle so please that oh so we're checking to see if that file exists and if it does then file dot Dilys and we just tell it the name of the file once is leaked so go here take the data pass pop it in there like this and that will delete our file so let me just go up here and add one more extra function here this is going to be delete save data and we're gonna use the J key to do that okay save that and there okay so they're all set up perfectly let me go back in here and now if I just play the game I'm gonna delete that save data we already have so if I hit J that's done and now if I play again I don't know why I stopped did that but if I hit l2 load now we don't get any message because there's no save data for it to access okay so perfect let's go ahead and make it so that this save system now actually does something so the first thing I'm going to do is go into our save manager I'm gonna make it so does this save manager is accessible from other scripts nice and easily so I'm just gonna make it a public static save manager so we're making a singleton instance so there's only one of it available and then when we awake will say instance equals this so I've used this in many other videos and if you haven't seen an action essentially it's a way of creating a single object that is accessible from every other script within the world so we can save this and what I can do then is actually we just have one extra thing up here I'm gonna create a public pool that will call has loaded to mesh everything else be able to tell hey has our save manager actually loaded some information and if it has then we could actually set that information so then in our load down here I'm gonna say when we've loaded something we'll say has loaded equals true and we're gonna make sure as soon as the game starts running so in this awake function we're gonna call that load like so so if there's any information load it will load it up in here so if we have information to load well let's go to our game manager so in my game Andrew here I have how many lives we have and I also have a respawn point here so what I'm gonna do is right here I'm gonna say if the save manager dot instance has loaded so now I'm going into the save manager script looking at the instance which is this object there's only one of it running in the world and I'm calling the R I'm checking it if it has load of something so if it has noticed something what that means it has some information so we're gonna tell it to go to the respawn point that it has set and we're going to tell us to set the lives to whatever has been saved so here I'm gonna say respawn points equals the save manager that instance - active safe so I'm looking at the active save data and getting the respawn position as there and I'm gonna move the player to that position so player controller that instance that transformed up position is going to the respawn point and then we're going to say the lives that we currently have will be equal to save manager that instant start active save - lives okay so that would be fine and dandy that's cool and have a look at what would happen there so if we go into our save manager here we have at the moment it's set but it has zero lives and all this so if we were to save the game now then a game would had zero lives the Seraph way and our player starts off with more lives than that so that doesn't really feel great but obviously when we first start the game and there won't be anything to load so it won't that problem won't immediately appear if I go look at my game manager here you see I have 10 lives to start off with so let's say for example we start the game we've got 10 lives and then we do something that makes the game save so the game saves and when it saves is that it has zero lives then when we load up the game again all of a sudden we'll be loading back in with zero lives again so what we're going to do is make sure that when we first start the game if the save manager has loaded then set the lives but if it hasn't loaded which means there's no save data which means we're essentially playing this the first time then tell the save manager that instance that active save to set the lives amount to be equal to however many lives we have so what that will do is then if I go ahead and play the game here once that compiles I play she'll see there we go straight away our lives bumps up to ten so then as soon as we save our lives will be stored in that way so let me just hit the Save button here so I saved that and now when I stop and play again there we go we have our 10 lives so perfect that's doing what we want let's also then make sure that I have down here a respawn Kover team that handles respawning the character and in here I'm gonna say okay well whenever we take away some lives tell the save manager that instance active save that lives to be the new lives amount like so okay so let's save that so that's how we're gonna handle our lives the next thing we're going to want to do is obviously if I go ahead and play here one of the most important elements is we want to save when we hit these checkpoints so I'm gonna play that box if I run forward hit the checkpoint perfect that's there but if I stop and play again obviously that doesn't do anything we're just back at the very start so I'm gonna dive into the checkpoint scripts that I have and in here we can see it's telling the game manager to set the respawn point to be there what we're gonna do is also tell the save manager that instance the active save respawn points should also be our transformed position and because this is a checkpoint we're gonna tell it at that instance to save the date so we're gonna say save and your dot instance dot save the information that we want to save so let's go ahead and say the script now jump back in and this time we should see if I go ahead and play open my little door run out here when I hit the checkpoint now if I die I respawn back here which is the way I want that to happen anyway so what I'm going to do is stop this running and when I play again we should see boom we're back at the checkpoint this is exactly where I want it to be and one thing that I want to have in this game as well is when I die at any point I want to let my player respawn which is perfectly fine you can see I'm using my lives that's fine as well but I want these watermelon to reappear when I die so I'm gonna switch the game manager if I jump back in here to my game manager here we have the player controller getting reset and all this I'm gonna comment this out so that this doesn't happen and what I'm gonna do instead is now that we're saving the check point position of the player I can just reload this scene so I'm gonna tell the scene manager to load scene and the scene I wanted to reload is the current one that's open so I can say see manager dot get active scene and get the name of that and tell it to reload this scene so now when I save go back in here let that compile and if I play with a run over you can see I set it back at the flag if I jump now and now if I die the pop back and the water mounds will reappear which is all perfectly good but you might also notice there's one little thing happening here that I don't want obviously and that is that my lives aren't going down so what's happening is I die I lose a life but then when I respawn I haven't saved the fact that I lost a life so why would I remember that I did that so what we're gonna do is make sure that whenever we sit whatever we respawn here we're also going to save the game so we're gonna say save manager that instance that save our data so save that let's go back in here and we'll do the one final thing that I wanted to set up in this little scene which is these boxes look at these boxes they don't they don't allow me to go backwards to my level because I hit this checkpoint and reload and we also just demonstrate I do lose my lives when I hit this stuff which is perfectly fine so what I need is these boxes to not reappear when we die so we're going to want to save that the fact that these are turned off so for that what I'm going to do is first of all I'm gonna play again here I'm going to delete my save like so so now I'll restart back at the start of the level which is perfectly fine and then what I'm gonna do is I'm going to go into my scripts here and I have a script that's controlling the button that we have above and when I switch it to being honor I'm gonna tell the save manager to set that variable that we set up before the active save door open is equal to whatever my own value is and then I can go up to the top here and in my start function I can do a check to say hey has the save manager loaded so it's the save manager that instance has loaded well then I should know whether this button is turned on or not so we can say is on value is equal to save manager that instance that active save door open and then I just have some code down here that will automatically check and see whether the button should be on or off so what I saved that if I go ahead and play now when I jump up here hit the button that box breaks when I hit my flag saves if I die I reload back here and a little door stays open there you go there's a brief little demonstration of how you can use that save data in different ways and how you can check it from different places obviously how you're gonna use it in your own game is gonna be very very dependent on what you want but it's really handy and really flexible because you can save a whole variety of things and most stuff that can be serializable can be saved as an XML information and most of that you'll want to save will be in the form of numbers and booths values and things like that but it's really handy to be able to do that I found it very very useful for games I've worked on in general and it makes saving so much more easy to do but there you go thanks for watching this tutorial I'll be back soon more tutorial goodness as I said earlier in the video make sure you go and wish list school kaboom right now on Steam and don't forget to hit the like button hit the subscribe button all that fun YouTube stuff that everybody tells you to do and come back soon for more tutorial goodness
Info
Channel: gamesplusjames
Views: 17,365
Rating: undefined out of 5
Keywords: unity, unity tutorial, learn unity, unity games, unity school, unity beginners, learn to code, unity c#, c#, unitysave, saving data in unity, unity save system, unity save manager, unity save xml, unity saving, unity save
Id: 8zjd7K_Ga48
Channel Id: undefined
Length: 28min 39sec (1719 seconds)
Published: Thu Apr 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.