Saving data between levels in Unity 2D - Tank game tutorial P16

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we are going to learn about preserving the data such as health value between scenes so if i enter this exit area i have been loaded into the next scene as you can see the health bar stays with the same value as was from the previous scene and if i stop the game and i press play we have a menu that allows us to start a new game or continue to the next level to the level 2 as well as if we stop the game and start again if we click start we're going to be loaded back into the first level of our game ok let's get going this video is part of the series of videos about creating a 2d top-down tank game we will explore different features of this game each as a standalone video hi i'm peter and welcome to sunny valley studio tutorials okay currently we have in our game only single sample scene i'll select it and select ctrl d to duplicate it and i will duplicate it two times now the current scene is a sample scene without an index i will rename it to level one okay reload the scene this should be good to go now the second scene i can call level two and the third scene i will call menu okay now our level one is the current scene and our tank is in this spot let's open up the level two this will look exactly the same but now i will select our player and i will move it using the arrow here somewhere let's say here so that we know that we have loaded a new scene since i will not create a new scene for this example i will reuse this old scene okay so this is level two we will start in this corner of our map now let's go to our menu and i will want to delete everything beside the main camera since we do not need it for our main menu now let's create a right click in the hierarchy let's select ui and i'm going to create a canvas i'm going to right click create ui and panel okay and we're going to select some image for our panel in our project we should have at the top of it some sort of a blue panel so i'll use it select the alpha to be full and this will be our panel and in this panel i'm going to right click create another panel for our buttons so that we can have two buttons start and continue i will use the anchor and hold shift and alt and select our anchor point to be the bottom point of our ui now i will select the panel and select f in the scene view and select the 2d view so that we can modify the size of our panel for the buttons so maybe first let's call it button panel and actually let's maybe decrease the height of it and then select the side hold alt so that we can modify or we can drag both sides so we have this smaller panel and this will be our button panel all i need to do is add to our button panel a vertical layout group i'm going to select the child alignment to be middle center and i will uncheck the child force expand height and i will add here and a button so right click ui and select a button and this will be our button it is pretty small so i will again hold one of the corners hold alt so that i can scale it in both directions and this will be our button i'm going to call it start or maybe continue button and i will expand the text of it set the text to be start or continue and i will change the font size to be a bit bigger and i will duplicate the continue button so select it ctrl d to duplicate it and i will change the name of it or the name of the game object to be start button okay open it up and change the text to be instead of continuous start and those buttons are too close so i will select our button panel our vertical layout group and i will add spacing so that we can have something like 60 points of spacing so now we have those buttons separate great this is our main menu let's save the scene and now we will need to code the logic behind those buttons and behind the save system so that we can load and save the data between scenes so we will need to have two game objects in the hierarchy so let's right click create and i'm going to create save system and i'm going to right click create a game manager for this simple tutorial we are going to use player prefs as the saving system but i have also a video series about creating a save system using a json file and to save the data to a file instead of the player prefs but for this simple example let's keep this simple i'm going to reset the transform of our save system so reset and game manager reset just to be safe great now we will need to add some logic to those two game objects so we will need to go to our scripts folder and i will create right click create script and i will call it game maybe let's start with save system so it's called type save system and let's open it up in visual studio okay great now as i have mentioned we are going to use player prefs so let's say the documentation for the player prefs okay so the player press is a class that stores player preferences between game sessions and it can store string float and integer values in the user's platform registry so we have couple of methods here we can get the float in a string and also set the float string and int and we can delete all keys we can check for example the set int we need to have a key value which is a string value of a key that we want to set the int with and we have the int the value that we want to save so we have the key name for example and the value that we want to save so this is a pretty basic way to save the data and we can use this player prefs to save the data between the scenes of our game so let's go back to unity okay let's delete the update and start and as i have mentioned before we will need to have a key values that are string values that we can use to load and save the data in our player prefs class so let's paste i will paste the string keys we will have a player health key between because we want to save the player health in our game we want to save the scene key so that we can load a different scene upon pressing the continue and i will have the save preset key so this will be important to check if we actually have a saved data in our game so those will be our keys that we'll be able to reuse now we will also need to have a separate class that will store the data of that we have loaded so we'll create a below our save system a public class and we are going to call loaded data and this will simply store the data that we have loaded so let's create public int and we are going to call player health let's set it to be minus one by default and public int scene index and we are going to set it to be minus one as well now let's create additional values here in the save system i will paste those first of all we will have a reference so the property of loaded data type so we'll know that if this is equal to null we do not have a saved data loaded and if this is not null anybody that wants to access the data will be able to access the safe system dot loaded data property we are going to also use the unity event for this i will need to right click quick action and select using unity engine.events since we are going to trigger with this event if we should set the continue button to be active if we actually have loaded some saved data into our game or if the saved data is empty and we want to block the players from being able to press the continue button and we are going to use initialized bull flag because we are going to load the data only once and at the beginning of our game when we enter the menu scene now with all those fields set let me paste the remaining code that we will use okay so first of all in the awake we are going to prevent the unity from destroying our save system so we want to persist that this game object the safe system between the different scenes so that we can persist the save system and the loaded data that we have in it let me show you the documentation for it so don't destroy onload do not destroy the target object when loading a new scene now this is basically the functionality that we want to achieve now when we enter the start method so when we load our save system in the main menu we want to set the is initialized and we are going to check if this is true we are going to return now this is maybe redundant code because we are only going to call the start method in the menu scene so maybe we did not need it so this will be one less bull flag in our code so start method now will only be called when we have entered the main menu since there is there will be our save system object since we call don't destroy unload the awake and start methods will never be called again because our game object will be persisted between the different scenes and in the start method we want to simply call if the result of the load data method is true or false the load data method simply checks if playerprefs.getint save preset key so the key that i have put as the last key is equal to one so this will only be one if we actually have the saved data in our player prefs if we have this data we are going to create a new loaded data object and we are going to load into the player health of it the player press dot get in the player health key again the key that we have defined at the top of our class and then get the scene key we're going to set the scene index as the player preps that get in the scene key and this will return true so we have loaded some data and in the start method if we have actually loaded the data we are going to call our own data loaded result unity event and this will allow us to set the continue button interactivity to be either false or true depending on if we have our data to load it or not now beside the loaded data method we are going to have the reset data so when we click the start we are going to simply delete all the keys so the player health key syn key and save preset key so we can start a new game and we will not be able to load the previously saved game now this is only important because we want to delete the player health so that our game manager will not set our player health at the first level to be a lower value than maximum health and this will be called when we call our start button so that we want to start a new game now we have discussed the load method we have also the saved data method and we are going to pass the scenic index and the player health and first of all we are going to check if we have loaded data if this is null then we want to create a new loaded data and save the data to our loaded data player health and scene index this will be important because we will want to save data in the previous scene and when we load a new scene we want to have the player health from the previous scene so this is why we have in our saved data the loaded data new object created if we already have the loaded data we will simply change the player health value to the current player health value and we have the scene index it will be saving the new scene index so that if we exit our game we will be able to reload the current scene that we are in and we also want to set the player prefs so basically we are saving the data about our current progress to the player prefs here so the player health scenic key and save preset key will be equal to 1 so that we can load the data great and below we have our loaded data class so this is it for our save system and now we will be able to use the save system in our game manager so let's go to unity now we have our save system game object so let's drag onto it the save system script and we have our keys and we have our own data loaded result unity event we want to add here the event and we want to drag the continue button object now as i have mentioned this will be triggered if we have successfully loaded data it will be set to be true if we do not have data it will be said to be false so i will select the no function select the button and select the interactable so now if we press play we should not have the player press data so as you can see the continue button was disabled if we had the data loaded it will be it will be available for the player to click ok so we know that this part works now we will need to create a game measure script so let's right click create a new c-sharp script let's call it game manager and let's open it up in visual studio okay great i mean i will delete the update and start methods and i will paste the fields that we will need to have in this game manager now first of all we will need to have the access to the player game object so that we can actually say set the health of our player to the data that we have loaded and we will need to have the access to the save system so that we can actually access the saved data now we will need to have the awake function when we call the don't destroy on load again we do not want to destroy the game manager we want it to persist across all the scenes that we have in our game now as i have mentioned the don't destroy unload will prevent the future scenes from calling the awake and start at the start of the game we want to load the player health to the player game object so to do that we are going to create an initialized method and this initialize method we will need to assign to the event when our game when our new scene was loaded so at the awake we are going to call scene manager and we do not have the reference to it so right click quick actions and we are going to be using here in the engine.scene management library now the scene manager let's see the documentation for it okay so the scene manager simply is a class that manages the scene at runtime so we can use it to for example load this in or they get the data about the current active scene and it it has couple of events so the scene loaded at the delegate that is notifying the listeners when the scene was loaded and that's exactly what we want to use to load the data about the player health when we load the new scene we want to set the player health to the value from the previous scene so let's go back to unity okay so the scene manager dot scene loaded this is our event and we are going to set plus equal to initialize and the initialize method needs to take the scene and the loaded scene mode values to be able to be assigned to our scene loaded event now the initialize method will simply debug.logs loaded gamer manager just so that we can see that our initialize method was called we're going to get the reference to our player so we have our game object player and in our game our player game object has only the player input and only inside it we have our tank that is the object that we actually move using the player input so we want to get the reference to our player and then if we want to set our health in our damageable script we will access the player get component in children and get a reference to our damageable script okay we are back in visual studio so we are going to get the we are going to find object of type player input and if we found if we have found it in the menus and we will not find it if we have found it we are going to set the player equals playerinput.gameobject great now we are also going to find object of type save system so we can have access to our loaded data object in our save system now if our loaded data is not null we will simply call our var damageable equals player.getcomponent in children damageable script which holds the reference tara to player health and we're going to call damageable.health equals the safesystem.loadeddata.playerhealth now for safety we could of course add here in this if if our player is not null just to be sure that we do not try to set the data to our player object which is now okay so this is our initialize method this will be called when we have loaded our scene now since our game manager has the access to the save system we are going to add some helper methods here so we are going to have load level method this will simply load the level if we have the data loaded in our save system we are going to simply load using the scenemanager.loadscene this scene with index from our loaded data and we are going to return else we are going to load the next level which simply loads the scenemanager.getactivescene build index so we're going to get the menu scene for example plus one and we are going to load the next scene and we are going to have the save data method that will simply set the if the player is not null we are going to call our save system save data we are going to call save scene manager get actives in build index 1 so we are going to save the next scene index and we're going to save the damageable.health value so the player health now i will explain why we save the build index 1 when we implement the exit collider in our scene so let's save our game manager let's go to the unity and assign our game manager our new script called game manager now to check if it works we are going to go to the file build settings and we should have the new window pop up we're going to go to the scenes folder and i'm going to drag the menu and level 2. i'm going to drag the menu as the first scene level 1 as the second scene and the level 2 as the first scene and the index starts from zero so zero one and two will be the indices of our scenes okay now in addition to that we will need to go to our canvas to our panel buttons panel and when we click on continue we will at the bottom of the inspector see the on click event let's add an event here and i'm going to drag our game manager and select our game manager and we should have load level so now we are going to rely on the load level to check if we have loaded the data in our save system we want to press the continue button and it should load the saved level so saved index from our saved data on start we are going to do the same start button add listener drag the game manager and again select the game manager and select the load level we could of course use the loader next level but the load level is more universal so now let's press play and we should see that continue is disabled since we do not have any data loaded from our save file or our player primes we can press start and we are in our level 1. now this is great but now we do not have a way to migrate from the level one to level two i'm going to save the menu scene and i'm going to go to level one select our player and focus on our player using f so this is our current map and what we will need to do is to have a way to transition to the next scene so i will simply right click select 2d price and square and i will call it exit since this is all this already has the sprite render i will set the sorting layer to be the bottom details i will select the move tool in the scene view and i will place it here so here will be the exit point of our level okay now we will need to have a custom script on it but before that let's add here a box collider 2d and we are going to set the box collider to be a trigger so that we can get the trigger event when our player triggers with the exit object now let's create a new script right click in the c scripts folder create and select script and i'm call i'm going to call it exit or exit level okay let's open it up in visual studio okay let's delete the update and start and all we will need to have here is the game manager reference and a layer mask so that we can detect if our player has collided with our game with our box collider so let's create on trigger enter 2d method and this will be triggered when we when our player has collided with the exit level game object now we will also need to have the awake method and the india way we are going to get the game manager since our game manager is persisted between scenes we cannot assign it directly to our exit level because it doesn't exist in our level 1 it exists in our menu and it will be kept between levels so we will always need to get the reference to it using the find object of type game manager now in the ontrigger enter we are going to check if and we will need to check if the collision layer is on our layer mask so to do that we are going to open parenthesis and we are going to use one left bit shift operation collision dot gameobject.layer which will simply create a layer mask from our gameobject layer and now we can use the big bit shift and operation to compare our layer mask from our collision game object with our player mask we are going to add another parenthesis to it and we are going to simply check if the result is not equal to zero so this is just a way to check if the layer from the game object is on the layer mask that we have created now if this is so we know that we have collided that the player has collided with our exit level game object and when it has we're going to call the our game manager and we're going to save the data save the data as you might recall saves the data about the player health as well as it saves go to definition it saves the build index of the current scene plus 1 so that we can save the next scene so the level 2 will be saved as our save saved data so that now we can be sure that when we press continue we will be loaded into the next level now let's go back to exit level script and after this we are going to call game manager dot load next level now of course if your next level is on the different index then right after the level one you might want to set it differently but basically this is the basic way to set it so let's save it let's go back to unity and now all we need to do is assign our exit level script onto our exit game object now make sure that your position on the transform of that of the exit is zero on z value so that we can actually collide with it and let's go back to our build settings so basically when we enter the exit game object we are going to save the index one plus one so two so we are going to save the index of level two as well as we are going to load the next level so we are going to get one so index from the level one plus one so we are going to basically load the level two okay but now there is an issue because we cannot really start from this level one scene we need to start from our menu scene before we go to the menu scene so we can actually create those objects we need to select our exit select our player mask and ensure that you have the player selected so we know that we want to collide with our player let's go back to our menu let's save our scene and one more thing that we will need to do is go to our scripts folder and open our damageable script okay so this script is responsible for keeping track of the tank's health and when we call our start method we always set the health to be max health so if we set our player health through the game manager when we enter the damageable script it will reset it to be max health to prevent it we are going to set the health int field to be 0 and we are going to go to start method and only set the health to maxself if our health field is equal to zero and this is important because start will be called after the game manager initialize method that we have created to initialize our player health okay let's save it let's go back to unity and now we should be able to press play again the continue button is not interactable so we need to press start and we are in our first level now here i'm going to destroy those enemies and get some damage so that we can see that we actually can preserve the value of health i'm going to drive towards it and i'm going to collide with it and we should be able to see that now we cannot really collide with it and one more thing that we will need to ensure that we have our exit on a layer that actually can collide with our player so we'll go to our edit and project settings and currently our exit is on the default layer and our player doesn't collide with default layers so i'll check the collision to be true so we can actually collide with the default layer okay great so now let's go back to our menu scenes since we cannot really start in our level one since we do not have the game manager or the save system loaded in our serial so let's go to our menu okay one thing that i've forgotten to do in the previous video was to add to our canvas to our panel button panel and start button the reset of our data now we need to be careful because if we load the level using load level method it will load the index of our next scene from our saved data so instead i want to first drag our save system and when we click start i want to simply reset the data and we can then call our game manager dot and select the method called load level okay now we can test our game let's press play now we should be able to press the start button since continue is unavailable and we have been loaded into our level one i'm going to destroy those tanks and emit those enemy tanks and get some damage so that we can see that we have actually received some damage okay i'm going to drive towards our exit point and we should be able now to collide with it now let's drive towards it and you can see that we have been loaded into our second level and as you can see our health was preserved between those scenes now if i stop our game and press play again we should see now the continue button is active and if we click it you can see that we were loaded to the second level as well as our health was preserved great so this concludes the tutorial about preserving the data between scenes in your game thank you very much for watching if you want to support me please take a look at my patreon website check out my udemy course about creating a 2d top-down shooter using the urp and unt2020 there will be a link with a discount in the description if you are interested leave a like subscribe leave a comment and i will see you in the next tutorial take care
Info
Channel: Sunny Valley Studio
Views: 8,052
Rating: undefined out of 5
Keywords: unity 2020 persist scenes, unity persist data between scenes, unity 2020 player health between scenes, unity keep data between levels, unity 2020 playerprefs, playerprefs save system unity, Unity top down, top down tank game, 2d tank game, unity 2d, game development, top down, tutorial, sunny valley studio, Unity 2020 tank game, unity 2020 saving data, unity 2020 saving to playerprefs, gamedev, indiedev, indie game development, sunnyvalleystudio
Id: CtBYJ7D3o1w
Channel Id: undefined
Length: 29min 51sec (1791 seconds)
Published: Wed Mar 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.