SAVE & LOAD SYSTEM in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so you've made a game and everything place nicely except the player has no way to save his progress well fear not in this video we'll have a look at saving game data locally and safely but first this video is sponsored by expressvpn expressvpn has several locations in over 90 different countries and is the fastest VPN provider out there by using a VPN you increase your security anonymity and it protects you from hackers expressvpn even uses a strong 256 bit encryption to help protect all your data for me one of the biggest perks has been that it lets me stream the office which isn't available in my country so thanks to express VPN for allowing me to experience Twite in HD a membership is less than $7 a month and they even offer a 30-day money-back guarantee so take back your internet privacy today and find out how you can get three months free by clicking the link in the description now whenever it comes to storing data in unity there are a few different ways to go about it the quickest and easiest way is by using the built-in player prefs with player prefs we can easily store single variables one by one I've already shown how you can use this to create a high score system so if that's something you're interested in definitely check out that video however it's not a great solution for saving player progress since it's really only meant to handle very small amounts of data and it's not at all secure another way is using a simple file format like JSON or XML to store your data the good thing about these formats is that they're designed to be super simple and easy to modify in fact you can just open them with a text editor and start changing stuff this makes them perfect for making your game multiple or for creating simple data bases during development to store stuff like items abilities and so on they can even be uploaded to a web server and displayed in the browser however this strength is also their weakness they're super easy to modify which also makes them not at all secure and so not ideal for saving player progress luckily there is a third option creating our own custom binary files custom binary files are very hard to read and modify because well they're in binary which also makes them much more secure and creating a binary file is actually fairly simple oh and yes this works on mobile as well so we start by creating a class in unity that contains the data we won as public variables we could for example have a string a float a bowl and an int array keep in mind that data types specific to unity like vector 3 or color aren't serializable this is not a big issue since these classes can often be represented using just the 4 based datatypes I make the 3 for example could just as well be stored in a float array with 3 elements now when we have the variables that we want to store we mark the class as serializable the next step is to use a binary formatting the goal of the binary formatter is to read the data of any class we feed it and turn it into binary zeros at once we then create a new file on the system through code where the binary format you can put this data when we want to load the data back into our game we simply open up the file have the binary formatted converted back from binary and put it into the unity class so with that explanation let's get started so I've gone ahead and set up this simple example level in here we have a player and this player has basically three primary pieces of data the first one is his position and I've created a player movement script that is going to change this over time he also has a player script containing a level and some health and just to visualize this a bit more I've created some UI here that has the level the health and the position shown the assets that I'm using for the UI is from the ultimate game UI pack it's available on the unity asset store you can of course pick it up if you think it's cool but it's not required in any way and if we play we can see that the position indeed does change over time and we can use these buttons here to adjust the level and health and as we do that these things are going to update under our player we can see the position and the level and health updating so now that we know what data we're working with let's try and create a class that will contain this data so if we open up our player script we can see that we have two variables in here we have a public in for the level and one for the health I also have a few methods in here but these are just for updating UI so you can just ignore those and of course on top of these two variables we also have a victor 3 storing or position but this is inside of the transform component let's go ahead and create a class that will store these three pieces of data so inside of our assets that's right click go create C sharp script let's call it player data and open it up in vicious 2 so let's go ahead and remove the two methods we can also delete the amount of behavior because this is not going to act as a component in our game so now we have a completely empty class and we're ready to start populating it with some variables the first one is pretty simple it's a public int containing the level then we'll have another public int containing the health and as for the position you might want to go ahead and create a public vector3 containing the position however as we talked about we aren't able to serialize stuff that is unity specific like a vector3 so instead let's go ahead and create a float array that is going to store three elements one for each coordinate in our position so now we've defined our data but we still need to tell the class how to get this from the player so to do this let's create a constructor for our class if you've never worked with constructors before they pretty much act as set up functions for our class so let's create a public player data and this is the syntax for creating a constructor this is going to take in the data from our player so it's going to take the player script and let's just call it player now we can take the data from our player script and store it inside of these three variables so we can go level equals player level and that's probably the simplest case we simply go to our player script and take the level variable and put it inside of our little variable in our data class we do the exact same thing for a health deposit health equal to player dot health however in the case of our position we do need to convert a little bit so here we can set our position equal to a new float array and this is going to have three elements one for the X 1 for the Y and one value Z and we can now go through and access each one of these elements that will start with the X so position index 0 is going to be equal to player will access the transform so dot transform dot position dot X and we can simply copy this line and paste it two more times so we'll access the second coordinate which is the Y and the third coordinate which is the Z so let's change these to y and z so you can see how really easily we can take these more advanced data types like a vector three and convert them to what they really are basically just an array of floats if you wanted to store a color you could do the exact same have one element for the red one for green one for blue and then maybe a fourth one for alpha so now that we've created I'll play a data class we're ready to continue but there's one very very important thing that we need to remember to do first and that is go to the top of this class and as an attribute so inside of these two square brackets market as system dot serializable and this just means that we will be able to save it in a file so let's save this class now let's head into unity and let's create another c-sharp script so right-click create c-sharp and this one is going to be responsible for actually doing this saving so let's call it something like save system let's double click to open it up in Visual Studio again we're going to delete the two functions here and remove the monobehaviour and actually want to go ahead and mark this class as static a static class is just a class that can't be instantiated because we don't want to accidentally create multiple versions of our save system except we want to make sure that we include the appropriate namespaces we can go ahead and remove system dart collections however we do want to be using system dot IO system dot IO is the namespace we use whenever we want to work with files on our operating system so we'll use this when creating and opening the actual save file then we also need to be using system runtime dart serialization dot for matters that binary yes that is indeed a thing if you have a hard time remembering this don't worry I do too I almost always look it up and as you might have guessed from the name of it this will allow us to access the binary formatter so let's go ahead and create a state function let's make it public static so we can call it from anywhere without an instance void and let's call it save player the function is going to take in a player and it's call him later now the first thing that we need to do is create a binary format or for us to use so I'll do binary format let's call it formatter and set it equal to a new binary formatter next we want to create a file to save to but first we probably want to decide where this file should be saved so let's create a string called path and set it equal to well the location of a file and could go ahead and just input some kind of location on your system here and the file would be saved to that location however the path that you want to use is probably going to completely depend on the operating system a path that works on Windows probably doesn't work on Mac and it's definitely not going to work on iOS or Android and also we probably don't want to make it too apparent where we're saving these files we don't want it to be inside of the project folder or some obvious location luckily unity has a really handy function called application dot persistent data path and this is just going to get a path to a data directory on the operating system that isn't going to suddenly change then we can add anything to this so we can create a stop file called player dot and since we're actually making our own file here and it's just a binary file we can use any file type that we want that's right it's completely up to you what you want to write I'm gonna write fun just to make this tutor a bit more fun and it's close it off now on a new line we can create a new file and each time we are working with a file we use this concept of a file stream a file stream is exactly what it sounds like it's a stream of data contained in a file and we can use a particular file stream to read and write from a file so let's create a variable of type file stream let's call it stream and set it equal to a new file stream here we want to give it the path and then we can define the file mode and this is whether or not we want to open the file or create one app into an already existing file or some other options we're just gonna do create so now we've created this file on our system and we're ready to write to it so let's go ahead and create some player data let's call it data and let's set it equal to a new player data and because we created this handy constructor here we can actually just go ahead and pass in our player and all this code is going to be run which means that the player data class actually just sets up itself so now that we have all the appropriate data formatted the way that it should be we're ready to insert this into a file let's do formatter dot serialize which means that we're going to write data to the file first this needs a file stream we'll input our stream variable and then some data in our case our player data finally when you're done writing data the file we want to close it off so will it go stream dot close and that's all the code that we need for saving let's also create a variable for loading some data public static and here we don't want to input void since we're going to be loading some data we probably want to return this data so let's create a public static player data let's call it load player and the first thing that we want to do in cure is get a path similar to what we did up here I'm just going to go ahead and copy this line for now if you want to make it a bit cleaner you can maybe separate this out from the two functions so that if you change it in one place it's going to change in both for now we'll just copy it we're then going to check if a file exists in this path so if file dot exists we want to check for the path then we want to call some code and if it does not well then we want to do some kind of error let's do debug that log error and we'll say save file not found in and it will output the path then we can just return no however if we do find a file which hopefully we do well then we want to do actually a lot of the same stuff that we do up here when saving the player first we want to open up a binary format err so binary format err let's call it formatter equals a new binder formatter then we want to open up a file stream so we want to go file stream stream equals new file stream again we'll feed it the path but this time we don't want to do fan mode create instead we want to do found out stud open to open up the already existing save file then we can read from this stream by going formatter dot DS serialized so it's not going to change it from binary back to the old readable format and the only thing that we need to feed it is the stream from a file we then store this data as with anything else in a variable so let's create a player data variable that's called Danna and set it equal to the result and it's going to give you a red line here and that's because we need to cast this we need to tell it what type of data we are working with so we're going to format it as player data so now we've cast this information into a player data type and finally we can go ahead and return the data of course there's one very important thing that we forgot and that is we always need to close the file stream so here we want to go stream dot close otherwise you're going to get some weird-looking errors and that is actually everything that we need to do for our save system which means that we are pretty much ready to try this out if we save this now and go into unity to make sure that we don't have any errors we actually have all the components needed to now save and load this data the only thing that's left to decide is when to trigger this behavior and that's completely up to you you can save at the end of a level you can save every ten seconds you can say when the user exits the game or you can save using buttons and I've gone ahead and created two buttons here a Save button and a load button so let's just trigger some code based on these buttons if you want to be really proper about this you can do it in some kind of game manager I'm just gonna do it inside the player script so here I'm gonna create two public functions so that we can call them from the buttons one is going to be public void safe player and here all we need to do is go save system and because this is a static class and function we can go dot save player and that's all we need then we can feed it in the player that we want to save in our case this player so we can just write this and it's also create a public void load player again we access the save system and we do load player and of course this outputs a player data so we want to take that data and put it back into our player let's create a player data variable let's call it data and set it equal to what we get when loading and then we can go level equals data level health equal start health and for the position that's create a vector3 called position and let's say position at X equal to data drop position and then we'll take the first element and that's actually copy this a few times so the second one is going to be Y the third one is going to be Z and it's going to go from 0 to 1 to 2 and then finally let's set transform start position equal to this position variable so now we've loaded back in our player data if we save this and go to unity we can now find the save and load buttons so I'm gonna select my Save button here I'm gonna go add an on click event and this is referencing an object I'm gonna drag in the player let's go under the player function and call this save player method and let's do the same thing for loading so load button add an event it's going to access the player object find the player script and call the load player function so now we should see that if we play and go ahead and mix around our level and health here so let's see we've increased to level seven our health is gone down to 28 and you can take note of our current position here that's save and if our game then changes that say we go up a few levels let's say to nine our health goes up again to 40 or 42 and this is our new position and we then hit load everything snaps right back and the cool thing is that this will even persist between game sessions so if we close down the game or change this around and then stop playing go back in and hit play again and we then hit load it's going to snap right back to these values and if we want to override our safe well then we simply hit save again so if we want to now have these values we can hit save let's stop playing hit play again hit load and voila everything's gonna update to the new values yay so that's pretty much it for this video now you can quickly see that it might become pretty slow and cumbersome to work with these files as the project gets bigger for each part of your game you need to create a save load function and a data class to convert from game play data to data that can be stored and while these files are hard to edit it can be done so if you're looking for a more long-term solution I really recommend picking up an asset like easy save it's just going to save you so much time and hassle it allows you to save unity specific data it can handle a bunch of data at once it can encrypt the data to make it really secure and you can even use it to save and load from the web I've used it before and really recommend it if you want to check it out this of course a link in the description also make sure to check out expressvpn simply click link in the description to find out how you can get three months for free other than that thanks for watching and I will see you in the next video thanks to of the awesome patreon supporters who donated in October and especially thanks to Andrew Cohen inco art Armand true VR systems simmer IO extended Blair Cheeta 3d Jeff Johnson infinity PBR Sybok mommy Danny Sullivan Chris Sheriff Abdullah pizza Murphy thanks along clear the set Fintan fence qeh shreya ste Turkish Kirk Ronan Tim Apple debauch burns cat Noah Kubasaki Gregory appears Larry tweet James Rogers Rathbun pecan Vania Erasmus Robert Bund car Jackson James P Anthony Patton pure sweet husky and a greasy you guys Rock
Info
Channel: Brackeys
Views: 788,657
Rating: undefined out of 5
Keywords: brackeys, unity, unity3d, how, to, howto, learn, course, tutorial, tutorials, fix, tip, game, development, develop, games, programming, coding, basic, basics, C#, save, savegame, custom, binary, custom binary files, JSON, XML, playerprefs, intermediate, advanced, formatter, secure, safe, file, format, load, easy save
Id: XOjd_qU2Ido
Channel Id: undefined
Length: 18min 20sec (1100 seconds)
Published: Sun Dec 02 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.