Thanks for watching! 🙂There's an *_issue_* with using _sceneUnloaded_ to Save the game that I overlooked when making this tutorial. If you're experiencing trouble with data being saved when transitioning from your gameplay scene (for example, back to the main menu), read the below. Because of how sceneUnloaded works, it triggers *after* everything in the scene has already been destroyed. Since we're calling SaveGame() in there, the IDataPersistenceObjects it would have called to update the GameData will already have been destroyed - hence the data would not get updated. The *_fix_* for this is to call SaveGame() anytime right before you load a scene rather than through the sceneUnloaded event. This will ensure data is Saved before the scene transition rather than afterwards. Apologies to anyone this inconveniences! I also address this in a bug fixes video which can be found here - ua-cam.com/video/yTWPcimAdvY/v-deo.html (see the "Removing the sceneUnloaded event (MissingReferenceException)" timestamp) I also just recently started up a Discord server where you're welcome to come ask questions, suggest a video topic, or just hang out! ➔ 📱discord.gg/99gcnaHFf9
@Gengo Astin Definitely. The idea here would be to call SaveGame() every time right before you load a scene (assuming you're going for an 'autosaving' kind of route with saving). So as one concrete example, you'd want to modify the _OnNewGameClicked()_ method to look as follows: public void OnNewGameClicked() { // create a new game - initializing the game data DataPersistenceManager.instance.NewGame(); // save the game right before we load the new scene, so that the new games data persists DataPersistenceManager.instance.SaveGame(); // load the new scene - which will load the saved data because of the sceneLoaded event we've hooked up SceneManager.LoadSceneAsync("SampleScene"); } Basically, anytime you do _SceneManager.LoadSceneAsync("..");_ , you'll want to call SaveGame() directly before. So this would also include the _OnContinueGameClicked()_ method or any other method where you're transitioning scenes. The big thing here that causes an error though is the sceneUnloaded event. So you'll want to remove that completely from your DataPersistenceManager along with the OnSceneUnloaded method. Otherwise, it could potentially try to call scripts that have been deleted as part of unloading the scene which will result in an error. I hope that helps clear this up a bit! 🙂
there is literally no words that can thank you enough for this video and your previous video on save systems but thank you for making a video with the git available so we can all see the code and take time to properly understand it I personally have been struggling to get a working save system implemented for the last 6 to 8 weeks for about 8 hours a day ("i know its not that hard now I'm new to unity and c# coding") but you have ended my struggles thanks to your tutorial and the git so that i could study the code and see how everything was working and I'm pleased to say that within a couple of hours with your tutorial i have successfully created and implemented my own version (largely similar to your version) of a save system with full understanding of how it works as opposed to what most tutorials do and say this is how you do it bye even assets for saving i couldn't understand until your videos thank you one more time please keep up the awesome stuff you do
Thanks so much for the kind words! I'm really glad to hear the tutorials helped! 🙂 These systems are definitely tough to understand and implement, so props to you for getting it working for your game!
This is by far the best structured and thought out tutorial I have come across regarding unity, regardless of the topic! It would be awesome to see more, especially the additive scene loading Keep up the awesome work
Thanks so much for the kind words! I'll be keeping that in mind for the additive scene loading. It's been requested a few times, I just have to figure out how to work that into where the series is currently at, haha.
that would be amazing if you would make a video for additive scenes too. However, i still might use this tutorial, coz my game has both additive and single scenes.
Actually i found it extremely hard to understand these massive info but once i just watched this video you mad every single small and hard detail clean and clear so i got them all thanks for this tutorial just go ahead!.
This is a complete usefull tutorial, i can never express my gratitude or thank you enough for such GREAT series. May God bless you in this Life and the after👍👍☺️😄
Hi, thank you for sharing this wonderful save / load system!! It's for sure the best present on You tube. I would love to see how this could work with additive scene, if you can in the future. Thank you a lot again !!!
Hello Trevor. Your videos have helped my current project immensely and I appreciate them. One small issue with my current step however is that my console always replies with a warning saying no data was found, a new game has to be created to be able to save, even if I have made a new game. I am not sure where this is going wrong and I am wondering if you have a fix for this. Thank you.
Im saving the scene on a save point but i i add the datapersistencemanager to my main menu it load the new scene how can i add the datapersistence manager to the main menu so i can delete the save game without it loading the save scene
Great Tutorial!! Can this method be used for saving scene object information? For example, like in Stardew Valley, where the crops planted in the farm scene remain intact even when you return from the village scene
Hi! I'm using your save & load system but the problem is I have more than 2 scene so how to save the specific scene and the position of the player on that scene. sorry for my English.
Hey there! For the first part of your question, I actually have a FAQ section in my Discord for a post titled 'How do I load the Most Recent Scene?' which should outline a path for saving a specific scene (or the most recent in that case). In short though, you'll save/load the scene name (or index) as part of your game data. As for saving the position in different scenes, I recommend creating something like a 'SceneData' class to store data specific to any given scene (like the players position) and then save multiple SceneData classes in your GameData. That'll let you keep track of things like the player position according to the scene. If that's confusing though - I recommend watching some videos on a subject called *Object Oriented Programming (OOP)* as that'll help you understand how to get more use out of how to store your game data. Hopefully that helps and best of luck to you! 🙂
Hi Trever, I've been following your videos for a while now I find them really easy for a beginner like me, thanks for the chance you give me to learn, one thing I don't understand regarding the coins, I tried to add some coins to the game but I see that the total number of coins always remains 5 can you help me understand. Thank you
Hey, great videos! So far they’ve proven to be exactly what I needed to get a rudimentary understanding on how to approach saving and loading data. Im wondering about one thing, though. When I save my data, should I instantly call for it to be reloaded if I need my data in scene to always correpsond to whatever is saved onto the disk? For example, if I save whenever a coin is picked up and some code would then check the present gamedata if the coin is indeed picked up, would I need to reload the gamedata between the saving and checking to ensure a match between both the file and runtime? Or is the gamedata itself also being updated in the process of saving data? Id figure its the latter, but rather safe than sorry.
Hey there! Really glad you found the videos helpful! This is a great question and I'll try to clarify a bit. When you Save data by calling SaveGame(), it updates the GameData variable in the DataPersistenceManager to be up to date with the IDataPersistence scripts. So in other words - when you save, it's basically putting the DataPersistenceManager GameData variable in sync with the most up to date data in your game. As such, you shouldn't need to reload after saving because everything becomes in sync when you call SaveGame(). Or TL;DR - it's the latter of what you said where the gamedata itself is also being updated in the process of saving data. That said, *until* you call SaveGame(), your GameData variable in the DataPersistenceManager will be _out of sync_ with the rest of your game. So in the Coin example you mentioned, I recommend keeping the changing state completely within the Coin.cs script and only reference the gamedata for (1) initialization of the state data during loading and (2) persisting of the current state data during saving. In this system, you want to let the individual script to keep track of the state and use the Save & Load system only to persist that state. It's certainly a tough concept to grasp, but I hope that all makes sense! 🙂
Ah, so if I don't want it to Save everything between Scenes but still not get deleted then all I have to do is the Object.DontDestroyOnLoad part of the tutorial? (my menu is already set up nicely, and I have my Save function called at a different time.) I guess my actual question(for clarity) is: will my data carry over from scene to scene now that DontDestroyOnLoad prevents DataPesistentManager from getting destroyed between scenes?
Another option than to use the DataPersistanceManager to keep references (and therefore more bookkeeping) is to use SOs to store each object state and then just iterate through those on save/load in each scene. Also correctly me if I'm wrong, but wont's save only persist objects in the current scene as they are the only ones registered via the interface to DPM?
Hey man great video! I have an issue though, I have a pause menu in my game. And when I go back to the main menu and then continue game from the main menu it just creates a new game... this is what i have attached to the menu button on the pause screen. public void MainMenu() { SceneManager.LoadSceneAsync("MainMenuScene"); Time.timeScale = 1.0f; } I hope this helps with figuring out the issue! Thanks man!
My DataPersistenceManager does not work properly. When I saved or loaded, dataPersistenceObjects becomes null. Please, reply Edit+++ I found out that I had not checked Reload Scene in Editor. Nice tutorial.
I'm experiencing issues when going back to the main menu scene from my game scene. When SaveGame() is called the gameData can't be accessed since my player script is already destroyed. How can I solve this? Thanks for help
Hey! 🙂Thank you for asking this! This is something I overlooked when creating this tutorial that I think others are going to run into. I updated the pinned comment with a fix for this and plan to address it in a video at the end of this series as well. In short - instead of saving data in sceneUnloaded (which is called AFTER the scene has already been destroyed) you'll want to Save the game anytime right before you load a scene (so that data is saved BEFORE the scene transition). So in your case, you'd want to call DataPersistenceManager.instance.SaveGame() in whatever method that's transitioning you back to the main menu. I would also recommend adding a call to SaveGame() in the MainMenu script when we click the new game button. If you do that, you can get rid of OnSceneUnloaded entirely in the DataPersistenceManager. I hope that helps!
I have watched a video about save and load games, the video is very good and it works in the game I made, but how can I save and load it while playing the game..? I have modified the code according to my needs, but it doesn't work 😭
For some reason the OnSceneLoaded event does not get triggered in my project no matter which scene I start with. I can debug my code to see the OnEnable() method gets called and the listener is added but nothing else ever happens after that. I even copy&pasted the code from github to make sure I didn't make any logical errors when following your video but that did not help either. Obviously this leads to an error during scene transitions since the dataPersistenceObjects list never gets filled upon first start, which means the SaveGame() method will run into an error when trying to go through its foreach()... loop. I have tried applying the bugfixes from the final video but that only shifted the issue around since OnSceneLoaded() still only ever gets executed in scenes loaded after the menu.
Hey there! 🙂Hmm, that's definitely strange. Here's a few things I can think of you can do to try and troubleshoot (which you might have already done). 1 - Just for troubleshooting purposes, try registering the sceneLoaded event in the Awake() method. You wouldn't want to do this here long term, but if it works in Awake() that might help you narrow it down to something strange going on with your OnEnable() method for that GameObject. 2 - According to this StackOverflow thread, it looks like some others have had this issue and fixed it by registering the event like - UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;. That could be worth a shot. - stackoverflow.com/questions/49781810/onsceneloaded-not-getting-called-on-scene-start 3 - Comment out your OnDisable() method that removes the listener to make sure that's not getting called for some strange reason. I imagine it isn't, but it's worth considering that the code to unsubscribe could be getting called somehow after it gets subscribed in OnEnable(). Definitely a strange issue, but I hope that helps a bit in narrowing it down!
@@ShapedByRainStudios Thanks for the suggestions - I came across some of those during my research as well but none seem to fix the error. Interestingly, when I copied the example code from the SceneManager documentation and add it to a (either existing or clear) scene in my game, it behaves exactly the same - all methods get called as expected except for OnSceneLoaded() as the event it is listening for apparently never gets triggered. On the other hand, both the ExampleCode script and your DataPersistenceManager work perfectly fine in a completely new project, no matter which Unity version I open it with, suggesting something in my project *somehow* prevents the event from being triggered even in a clean scene. Seems your code is obviously not to blame here. 😅
@@touzimsky That's so strange! The only thing I can think of is that maybe it's a Unity setting somewhere, but otherwise I'm at a loss. I'm sure you'll figure it out eventually though! Best of luck! 🙂
@@ShapedByRainStudios I actually went through all the settings, comparing my original project to the new one I created to test against, and I think I found it! Under "Project Settings"/"Editor" you can find the "Enter Play Mode Options" setting. If this is deactivated, or activated and "Reload Scene" is checked as well, everything works as expected. IIRC somebody recommended deactivating the "Reload Scene" option to accelerate entering play mode, probably by not reloading the whole scene. This would explain why the sceneLoaded event never gets triggered for the initial scene but all others: it NEVER ACTUALLY GETS LOADED! 🤯 Thanks for believing in me Trever! 🥳😅 Time to dive into the third episode now.
@@touzimsky Oh interesting! Thank you for sharing what you found! I imagine others are going to run into this and I'm certain these comments will save them some time! 🙂 Best of luck with the rest of the tutorial videos!
Hi, your tutorials are amazing!!! you enplane in a clear and professional way and in a good paste. I'm having trouble with creating a new game. when i try to create a new one it gives me a warning: " you are trying to create a MonoBehaviour using the `new` keyword. this is not allowed. MonoBehaviours can only be added using AddComponent(). Alternative, your script can inherit from ScriptableObject or no base class at all UnityEngine.MonoBehaviour:.ctor() " do you know how to solve it? Edit: I fixed it by doing what you said in the comment but my data isn't saving yet, and then my script isn't finding the data.
Thank you for the kind words and I'm glad you're making progress! If that FindObjectsOfType call isn't finding the IDataPersistence script - it could be because (1) the script doesn't exist on any gameobjects in the scene or (2) the gameobject with the IDataPersistence script is disabled in the scene when that call happens. Those are the two things I can think of at least. You can pass in an optional parameter to the FindobjectsOfType method as true to find disabled gameobjects if the latter is the case. The docs for that can be found here. - docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html I hope that helps a bit and best of luck! It sounds like you're doing a good job working your way through it! 🙂
@@ForIEqualsZero Hmm. I'm not sure which script you're referring to, but I'm assuming maybe the IDataPersistence or GameData scripts? Here are some notes which will hopefully help clear those up. IDataPersistence.cs - this is an interface, which means that other C# classes can 'implement' it. It doesn't need to be put on any gameobject, it just needs to exist in your scripts folder so that other scripts can reference it. GameData.cs - this is just a normal C# object we're using to keep track of our game data. We're creating it using the 'new' keyword in the DataPersistenceManager, so it doesn't need to be attached to any gameobject in the scene. I would also recommend comparing your code against the Github project for this video. Some classes are monobehaviours and others are not. I would click through them and make sure your code matches up. Here's a link to the projects state by the end of this video (see the branches for other videos) - github.com/trevermock/save-load-system/tree/2-save-load-implemented/Assets/Scripts/DataPersistence
@Trever Mock Yep, your Save/Load System tutorial series is just what I am looking for. Thanks for the link to the playlist. By the way. The link to your discord isn't working. It keeps giving me the follow error when I try to join. "Whoops...unable to accept invite"
Right on and thank you for the heads up! It seems that the link still takes me to the Discord server, when I click it, so that's definitely strange. You can try this temporary link (expires in 7 days) instead - discord.gg/PPsx4k5z . Let me know if for some reason that doesn't work as well and I'll try to figure out what's going on.
AHA! I incorrectly assigned my GameData in the SaveSlot script, calling it as "public GameData gameData" and not from the SetData(GameData data) method itself, causing it to pull the initialized gameData and not the loaded "data". Thank you so much in your help, looking over the files had me so stumped, and finally I was able to get through it. The only one left is selecting NewGame doesn't initialize data, despite it calling that function and everything. That one is bizarre as heck. Gonna recheck FileDataHandler and DataPersistenceManager again, despite them being correct last time I did. Do you remember if anything else has sway over the OnNewGameClicked() function in your MainMenu script? Thank you again :)
I also feel like the way everything is set up I'd be hitting an error message while playing, it wouldn't play as intended, or the unity console would give me an error which would refuse the game from starting. From what I can see it's just not calling the NewGame() function "this.gameData = new GameData();" which, from what I've seen from trying to do this in SaveSlots SHOULD be returning the initialized data, and NOT the loaded data. So it's a real head scratcher... Upon attaching a debug.log("New game started"); in NewGame(), it does, in fact, call the debug.log... so what on earth... lol. Why doesn't it just wanna initialize? :S
Hey! I'm glad to hear the tutorial was helpful! 🙂I'm a bit unsure what you're asking. Are you asking how to Save/Load through buttons rather than automatically? If so, I imagine it should be very similar to how we set up the Main Menu buttons in this tutorial, except you'd call SaveGame/LoadGame from different spots depending on how you want it to work. If you're running into specific trouble/issues, you're welcome to let me know and I can try to help as time allows.
Should DataPersistenceManager be a Monobehavior if it doesn't have state or any visual representation in the game? Is the Monobehavior needed to persist the singleton across scenes or will regular class singletons also persist?
Hey there! 🙂 I'm unsure what you mean by an 'Android control', but unfortunately, I'm not very experienced with Android+Unity development and wouldn't feel comfortable providing information or guidance on that topic unless it relates to a specific issue you're having regarding these tutorials. Best of luck to you!
Don't know if anyone is having this problem but calling loadGame() in OnSceneLoaded give massive errors in Builts, you have to wait a second bebfore calling the Methods. Don't know why tho.
Im having some troubles. I only have one other scene that the player can actually play and I want to reload the scene when he dies or chooses to. But the problem is, that the saved gameData is not getting reset when I call the NewGame(); function. Anybody know how I can fix it?
Hey there! Unfortunately, I'm not sure if I have enough info to give solid direction on a fix - but here's how I would start with troubleshooting. Put Debug.Log(..) statements in your NewGame(), LoadGame(), and SaveGame() methods to ensure they're getting called when you think they are. There's a good chance it either (1) NewGame() might not be getting called at the right time or (2) the call to NewGame() getting overwritten by a call to LoadGame() or in some other way. If that's the case, be sure to call SaveGame() after starting a NewGame() so that it properly overwrites your saved data with New Game data. I hope that helps a bit and best of luck to you! 🙂
@@ShapedByRainStudios I have a related question: when I try to load a new game i get all of my data related to items collected reset, but my simpler data (health, and player position) do not get reset. I tried debugging, as suggested above, and explicitly put a SaveGame() call immediately after my NewGame() call, but still not luck. Any ideas?
I have copied the tutorial perfectly, but what happens is that when I press "new game" my player puts in the wrong position. It is put in the (0,0,0). How can I make it go where I want it?
Hey! 🙂 When you start a 'New Game' - the data defaults to what's in your GameData constructor method. In these tutorials, we used Vector2.zero which will start the player at (0,0). If you want the player to start at something other than that, you'll just need to change it in that GameData constructor like so - _playerPosition = new Vector2(20, 54);_
Hello, I'm experienced some errors like didn't detect the interactable code in newGameButton.interactable = false; continueGameButton.interactable = false; Even the Using UnityEngine.UI; how can I do it? I hope it helps. Thank you from Philippines
Hey there! 🙂 It's difficult to give solid troubleshooting steps based on the info provided, but here are a couple things that come to mind you can check. 1. Restart Unity and your Code Editor. When you launch the code editor, also make sure you launch it through Unity by opening a Script there. 2. Ensure that the buttons are declared in that script and are the correct variable type (see that section of the video). Best of luck!
Thanks for posting these videos. I'm currently having a problem that I couldn't find a solution to in the Bug Fixes video. These following lines have been giving me errors. private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded(); SceneManager.sceneUnloaded += OnSceneUnloaded(); } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded(); SceneManager.sceneUnloaded -= OnSceneUnloaded(); }/**/ public void OnSceneLoaded(Scene scene, LoadSceneMode mode) {} public void OnSceneUnloaded(Scene scene) {} Any ideas on how to fix this? Do you think this is because I'm using the wrong version of Unity? (I'm using 2019.4) (error CS0029: Cannot implicitly convert type 'void' to 'UnityEngine.Events.UnityAction) (error CS7036: There is no argument given that corresponds to the required formal parameter 'scene' of 'DataPersistenceManager.OnSceneUnloaded(Scene))
Thanks for watching! 🙂There's an *_issue_* with using _sceneUnloaded_ to Save the game that I overlooked when making this tutorial. If you're experiencing trouble with data being saved when transitioning from your gameplay scene (for example, back to the main menu), read the below.
Because of how sceneUnloaded works, it triggers *after* everything in the scene has already been destroyed. Since we're calling SaveGame() in there, the IDataPersistenceObjects it would have called to update the GameData will already have been destroyed - hence the data would not get updated.
The *_fix_* for this is to call SaveGame() anytime right before you load a scene rather than through the sceneUnloaded event. This will ensure data is Saved before the scene transition rather than afterwards.
Apologies to anyone this inconveniences! I also address this in a bug fixes video which can be found here - ua-cam.com/video/yTWPcimAdvY/v-deo.html (see the "Removing the sceneUnloaded event (MissingReferenceException)" timestamp)
I also just recently started up a Discord server where you're welcome to come ask questions, suggest a video topic, or just hang out! ➔ 📱discord.gg/99gcnaHFf9
@Gengo Astin Definitely. The idea here would be to call SaveGame() every time right before you load a scene (assuming you're going for an 'autosaving' kind of route with saving). So as one concrete example, you'd want to modify the _OnNewGameClicked()_ method to look as follows:
public void OnNewGameClicked()
{
// create a new game - initializing the game data
DataPersistenceManager.instance.NewGame();
// save the game right before we load the new scene, so that the new games data persists
DataPersistenceManager.instance.SaveGame();
// load the new scene - which will load the saved data because of the sceneLoaded event we've hooked up
SceneManager.LoadSceneAsync("SampleScene");
}
Basically, anytime you do _SceneManager.LoadSceneAsync("..");_ , you'll want to call SaveGame() directly before. So this would also include the _OnContinueGameClicked()_ method or any other method where you're transitioning scenes.
The big thing here that causes an error though is the sceneUnloaded event. So you'll want to remove that completely from your DataPersistenceManager along with the OnSceneUnloaded method. Otherwise, it could potentially try to call scripts that have been deleted as part of unloading the scene which will result in an error.
I hope that helps clear this up a bit! 🙂
Please do a tutorial on additive!
I'd love to watch an Additive Scene Loading video from you. Thanks for your brilliant work. It helped me a lot.
there is literally no words that can thank you enough for this video and your previous video on save systems but thank you for making a video with the git available so we can all see the code and take time to properly understand it I personally have been struggling to get a working save system implemented for the last 6 to 8 weeks for about 8 hours a day ("i know its not that hard now I'm new to unity and c# coding") but you have ended my struggles thanks to your tutorial and the git so that i could study the code and see how everything was working and I'm pleased to say that within a couple of hours with your tutorial i have successfully created and implemented my own version (largely similar to your version) of a save system with full understanding of how it works as opposed to what most tutorials do and say this is how you do it bye even assets for saving i couldn't understand until your videos thank you one more time please keep up the awesome stuff you do
Thanks so much for the kind words! I'm really glad to hear the tutorials helped! 🙂 These systems are definitely tough to understand and implement, so props to you for getting it working for your game!
I like your style and way of teaching, clear and to the point. Thanks! Please keep up the good work.
Thank you so much for the kind words! 🙂
Speaking with no break is a bit difficult for a non-native English speaker to understand....BUT, YOUR TUTORIAL SAVE MY GAME! I give you big thanks!!!
Just implemented this into my game im working on! Thank you for this!
No problem! Really glad you found it helpful! 🙂
This is by far the best structured and thought out tutorial I have come across regarding unity, regardless of the topic!
It would be awesome to see more, especially the additive scene loading
Keep up the awesome work
Thanks so much for the kind words! I'll be keeping that in mind for the additive scene loading. It's been requested a few times, I just have to figure out how to work that into where the series is currently at, haha.
You have been a great help these tutorials are quick and to the point, but at the same time easy to follow along with. Thank you for your help
that would be amazing if you would make a video for additive scenes too. However, i still might use this tutorial, coz my game has both additive and single scenes.
Straight to the subject, this was a confusing topic for me but this video made it seem simple. Best teacher on yt 😁
Really glad you found the video helpful and thank your for the kind words! That means a lot! 🙂
Actually i found it extremely hard to understand these massive info but once i just watched this video you mad every single small and hard detail clean and clear so i got them all thanks for this tutorial just go ahead!.
I'm really glad the tutorial helped and I appreciate the kind words! 🙂
This is a complete usefull tutorial, i can never express my gratitude or thank you enough for such GREAT series. May God bless you in this Life and the after👍👍☺️😄
Amazing tutorial! But I wanted to ask what to do if I have a couple of scene and I wanna load the last one the player have been in.
Excellent video! Some of the highest quality Unity content I’ve seen. Path of ren looks sick too :) Huge fan of yours; keep up the awesome work!
Thank you so much! Really glad you think so and appreciate your kind words a ton! 🙂
amazing tutorial as always! Thank you so much! Also would love to see how your workflow works with additive scene loading! Thank you for making this
Hi, thank you for sharing this wonderful save / load system!! It's for sure the best present on You tube. I would love to see how this could work with additive scene, if you can in the future. Thank you a lot again !!!
Thank you so much! With this video I was able to complete a final for my class
Right on! Really glad to hear the video helped! 🙂
thank you very much, u show the solution I was looking for for a last few days
How does this channel not have more subs?! Great job!
That means a lot and thank you for the kind words! 🙂
Please do an additive scene video! This has been amazing :)
Very useful, will use this later
Awesome! Glad to hear! 🙂
Many thanks Trever. Loved the tutorial!
I love you and your tutorials
Thank you so much for the kind words! 🙂
Really helpful, thanks! You earned yourself a sub
Really glad to hear that it was helpful and appreciate the sub! 🙂
Some of the best videos I have found, thank you so much for all the time you put into helping others with their projects!
Thanks!
Thank you! Great work. Big help to my game. I also just joined your discord.
You're welcome! And right on! Glad to have you there! 🙂
Hello Trevor. Your videos have helped my current project immensely and I appreciate them. One small issue with my current step however is that my console always replies with a warning saying no data was found, a new game has to be created to be able to save, even if I have made a new game. I am not sure where this is going wrong and I am wondering if you have a fix for this. Thank you.
To be more specific, a new game isnt made or saved as a file even though i click new game
Amazing tutorial! Thank you :)
Im saving the scene on a save point but i i add the datapersistencemanager to my main menu it load the new scene how can i add the datapersistence manager to the main menu so i can delete the save game without it loading the save scene
I am totally interested in the "Adding Scene" version of this Save & Load System ;)
Hi Thanks for your tutorial!
Really glad you found it to be helpful and thank you for the donation! 🙂
If I switch to another scene (level2), what happens when we reload that scene, sir
Please do make a video on additive ! Thanks
Great Tutorial!! Can this method be used for saving scene object information? For example, like in Stardew Valley, where the crops planted in the farm scene remain intact even when you return from the village scene
i can load the game properly but when i try to make a new game it also loads the game. And also how would i make so load game loads a certain scene
nice thanks, helped a lot
Hi! I'm using your save & load system but the problem is I have more than 2 scene so how to save the specific scene and the position of the player on that scene.
sorry for my English.
Hey there! For the first part of your question, I actually have a FAQ section in my Discord for a post titled 'How do I load the Most Recent Scene?' which should outline a path for saving a specific scene (or the most recent in that case). In short though, you'll save/load the scene name (or index) as part of your game data.
As for saving the position in different scenes, I recommend creating something like a 'SceneData' class to store data specific to any given scene (like the players position) and then save multiple SceneData classes in your GameData. That'll let you keep track of things like the player position according to the scene. If that's confusing though - I recommend watching some videos on a subject called *Object Oriented Programming (OOP)* as that'll help you understand how to get more use out of how to store your game data.
Hopefully that helps and best of luck to you! 🙂
useful information thank you
Hi Trever, I've been following your videos for a while now I find them really easy for a beginner like me, thanks for the chance you give me to learn, one thing I don't understand regarding the coins, I tried to add some coins to the game but I see that the total number of coins always remains 5 can you help me understand.
Thank you
Hey, great videos! So far they’ve proven to be exactly what I needed to get a rudimentary understanding on how to approach saving and loading data. Im wondering about one thing, though. When I save my data, should I instantly call for it to be reloaded if I need my data in scene to always correpsond to whatever is saved onto the disk?
For example, if I save whenever a coin is picked up and some code would then check the present gamedata if the coin is indeed picked up, would I need to reload the gamedata between the saving and checking to ensure a match between both the file and runtime? Or is the gamedata itself also being updated in the process of saving data? Id figure its the latter, but rather safe than sorry.
Hey there! Really glad you found the videos helpful! This is a great question and I'll try to clarify a bit.
When you Save data by calling SaveGame(), it updates the GameData variable in the DataPersistenceManager to be up to date with the IDataPersistence scripts. So in other words - when you save, it's basically putting the DataPersistenceManager GameData variable in sync with the most up to date data in your game. As such, you shouldn't need to reload after saving because everything becomes in sync when you call SaveGame().
Or TL;DR - it's the latter of what you said where the gamedata itself is also being updated in the process of saving data.
That said, *until* you call SaveGame(), your GameData variable in the DataPersistenceManager will be _out of sync_ with the rest of your game. So in the Coin example you mentioned, I recommend keeping the changing state completely within the Coin.cs script and only reference the gamedata for (1) initialization of the state data during loading and (2) persisting of the current state data during saving. In this system, you want to let the individual script to keep track of the state and use the Save & Load system only to persist that state.
It's certainly a tough concept to grasp, but I hope that all makes sense! 🙂
Ah, so if I don't want it to Save everything between Scenes but still not get deleted then all I have to do is the Object.DontDestroyOnLoad part of the tutorial? (my menu is already set up nicely, and I have my Save function called at a different time.)
I guess my actual question(for clarity) is: will my data carry over from scene to scene now that DontDestroyOnLoad prevents DataPesistentManager from getting destroyed between scenes?
Another option than to use the DataPersistanceManager to keep references (and therefore more bookkeeping) is to use SOs to store each object state and then just iterate through those on save/load in each scene. Also correctly me if I'm wrong, but wont's save only persist objects in the current scene as they are the only ones registered via the interface to DPM?
Hey man great video! I have an issue though, I have a pause menu in my game. And when I go back to the main menu and then continue game from the main menu it just creates a new game... this is what i have attached to the menu button on the pause screen.
public void MainMenu()
{
SceneManager.LoadSceneAsync("MainMenuScene");
Time.timeScale = 1.0f;
}
I hope this helps with figuring out the issue! Thanks man!
Thank you!
My DataPersistenceManager does not work properly.
When I saved or loaded, dataPersistenceObjects becomes null.
Please, reply
Edit+++
I found out that I had not checked Reload Scene in Editor.
Nice tutorial.
you are my new brackey
I'm experiencing issues when going back to the main menu scene from my game scene. When SaveGame() is called the gameData can't be accessed since my player script is already destroyed. How can I solve this? Thanks for help
Hey! 🙂Thank you for asking this! This is something I overlooked when creating this tutorial that I think others are going to run into. I updated the pinned comment with a fix for this and plan to address it in a video at the end of this series as well.
In short - instead of saving data in sceneUnloaded (which is called AFTER the scene has already been destroyed) you'll want to Save the game anytime right before you load a scene (so that data is saved BEFORE the scene transition).
So in your case, you'd want to call DataPersistenceManager.instance.SaveGame() in whatever method that's transitioning you back to the main menu. I would also recommend adding a call to SaveGame() in the MainMenu script when we click the new game button. If you do that, you can get rid of OnSceneUnloaded entirely in the DataPersistenceManager.
I hope that helps!
@@ShapedByRainStudios Thank you for a well written explanation! This helped me solve the issue :)
I have watched a video about save and load games, the video is very good and it works in the game I made, but how can I save and load it while playing the game..? I have modified the code according to my needs, but it doesn't work 😭
For some reason the OnSceneLoaded event does not get triggered in my project no matter which scene I start with. I can debug my code to see the OnEnable() method gets called and the listener is added but nothing else ever happens after that. I even copy&pasted the code from github to make sure I didn't make any logical errors when following your video but that did not help either.
Obviously this leads to an error during scene transitions since the dataPersistenceObjects list never gets filled upon first start, which means the SaveGame() method will run into an error when trying to go through its foreach()... loop.
I have tried applying the bugfixes from the final video but that only shifted the issue around since OnSceneLoaded() still only ever gets executed in scenes loaded after the menu.
Hey there! 🙂Hmm, that's definitely strange. Here's a few things I can think of you can do to try and troubleshoot (which you might have already done).
1 - Just for troubleshooting purposes, try registering the sceneLoaded event in the Awake() method. You wouldn't want to do this here long term, but if it works in Awake() that might help you narrow it down to something strange going on with your OnEnable() method for that GameObject.
2 - According to this StackOverflow thread, it looks like some others have had this issue and fixed it by registering the event like - UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;. That could be worth a shot. - stackoverflow.com/questions/49781810/onsceneloaded-not-getting-called-on-scene-start
3 - Comment out your OnDisable() method that removes the listener to make sure that's not getting called for some strange reason. I imagine it isn't, but it's worth considering that the code to unsubscribe could be getting called somehow after it gets subscribed in OnEnable().
Definitely a strange issue, but I hope that helps a bit in narrowing it down!
@@ShapedByRainStudios Thanks for the suggestions - I came across some of those during my research as well but none seem to fix the error.
Interestingly, when I copied the example code from the SceneManager documentation and add it to a (either existing or clear) scene in my game, it behaves exactly the same - all methods get called as expected except for OnSceneLoaded() as the event it is listening for apparently never gets triggered.
On the other hand, both the ExampleCode script and your DataPersistenceManager work perfectly fine in a completely new project, no matter which Unity version I open it with, suggesting something in my project *somehow* prevents the event from being triggered even in a clean scene.
Seems your code is obviously not to blame here. 😅
@@touzimsky That's so strange! The only thing I can think of is that maybe it's a Unity setting somewhere, but otherwise I'm at a loss. I'm sure you'll figure it out eventually though! Best of luck! 🙂
@@ShapedByRainStudios I actually went through all the settings, comparing my original project to the new one I created to test against, and I think I found it! Under "Project Settings"/"Editor" you can find the "Enter Play Mode Options" setting. If this is deactivated, or activated and "Reload Scene" is checked as well, everything works as expected.
IIRC somebody recommended deactivating the "Reload Scene" option to accelerate entering play mode, probably by not reloading the whole scene. This would explain why the sceneLoaded event never gets triggered for the initial scene but all others: it NEVER ACTUALLY GETS LOADED! 🤯
Thanks for believing in me Trever! 🥳😅 Time to dive into the third episode now.
@@touzimsky Oh interesting! Thank you for sharing what you found! I imagine others are going to run into this and I'm certain these comments will save them some time! 🙂 Best of luck with the rest of the tutorial videos!
Hi, your tutorials are amazing!!! you enplane in a clear and professional way and in a good paste. I'm having trouble with creating a new game. when i try to create a new one it gives me a warning: " you are trying to create a MonoBehaviour using the `new` keyword. this is not allowed. MonoBehaviours can only be added using AddComponent(). Alternative, your script can inherit from ScriptableObject or no base class at all UnityEngine.MonoBehaviour:.ctor() " do you know how to solve it? Edit: I fixed it by doing what you said in the comment but my data isn't saving yet, and then my script isn't finding the data.
Thank you for the kind words and I'm glad you're making progress! If that FindObjectsOfType call isn't finding the IDataPersistence script - it could be because (1) the script doesn't exist on any gameobjects in the scene or (2) the gameobject with the IDataPersistence script is disabled in the scene when that call happens. Those are the two things I can think of at least.
You can pass in an optional parameter to the FindobjectsOfType method as true to find disabled gameobjects if the latter is the case. The docs for that can be found here. - docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html
I hope that helps a bit and best of luck! It sounds like you're doing a good job working your way through it! 🙂
@@ShapedByRainStudios I have a problem with that. I cant put the script on any game object because its not a MonoBehaviour.
@@ForIEqualsZero Hmm. I'm not sure which script you're referring to, but I'm assuming maybe the IDataPersistence or GameData scripts? Here are some notes which will hopefully help clear those up.
IDataPersistence.cs - this is an interface, which means that other C# classes can 'implement' it. It doesn't need to be put on any gameobject, it just needs to exist in your scripts folder so that other scripts can reference it.
GameData.cs - this is just a normal C# object we're using to keep track of our game data. We're creating it using the 'new' keyword in the DataPersistenceManager, so it doesn't need to be attached to any gameobject in the scene.
I would also recommend comparing your code against the Github project for this video. Some classes are monobehaviours and others are not. I would click through them and make sure your code matches up. Here's a link to the projects state by the end of this video (see the branches for other videos) - github.com/trevermock/save-load-system/tree/2-save-load-implemented/Assets/Scripts/DataPersistence
@Trever Mock Yep, your Save/Load System tutorial series is just what I am looking for. Thanks for the link to the playlist. By the way. The link to your discord isn't working. It keeps giving me the follow error when I try to join. "Whoops...unable to accept invite"
Right on and thank you for the heads up! It seems that the link still takes me to the Discord server, when I click it, so that's definitely strange.
You can try this temporary link (expires in 7 days) instead - discord.gg/PPsx4k5z . Let me know if for some reason that doesn't work as well and I'll try to figure out what's going on.
@@ShapedByRainStudios the temp link worked
AHA! I incorrectly assigned my GameData in the SaveSlot script, calling it as "public GameData gameData" and not from the SetData(GameData data) method itself, causing it to pull the initialized gameData and not the loaded "data".
Thank you so much in your help, looking over the files had me so stumped, and finally I was able to get through it. The only one left is selecting NewGame doesn't initialize data, despite it calling that function and everything. That one is bizarre as heck. Gonna recheck FileDataHandler and DataPersistenceManager again, despite them being correct last time I did. Do you remember if anything else has sway over the OnNewGameClicked() function in your MainMenu script?
Thank you again :)
I also feel like the way everything is set up I'd be hitting an error message while playing, it wouldn't play as intended, or the unity console would give me an error which would refuse the game from starting. From what I can see it's just not calling the NewGame() function "this.gameData = new GameData();" which, from what I've seen from trying to do this in SaveSlots SHOULD be returning the initialized data, and NOT the loaded data. So it's a real head scratcher... Upon attaching a debug.log("New game started"); in NewGame(), it does, in fact, call the debug.log... so what on earth... lol. Why doesn't it just wanna initialize? :S
i have do the same but when i click New Game the position of the player still the same
Hello I really like your trusted But can you please tell me how to make control by buttons (I mean diologists)
Tutorials sorry
Hey! I'm glad to hear the tutorial was helpful! 🙂I'm a bit unsure what you're asking. Are you asking how to Save/Load through buttons rather than automatically? If so, I imagine it should be very similar to how we set up the Main Menu buttons in this tutorial, except you'd call SaveGame/LoadGame from different spots depending on how you want it to work. If you're running into specific trouble/issues, you're welcome to let me know and I can try to help as time allows.
Hello Trever does this work for 3d also
Hey there! Yeah, this should work fine for 3D. To my knowledge, nothing in this video is 2D or 3D specific. Best of luck! 🙂
Should DataPersistenceManager be a Monobehavior if it doesn't have state or any visual representation in the game? Is the Monobehavior needed to persist the singleton across scenes or will regular class singletons also persist?
Oh I see it gives you a hook into the Unity callbacks which you're going to need at some point even with a class singleton
what is the upside to additive scene loading?
How awesome you are !
Hello Can you please tell me how to make an Android control with dialogs?
Hey there! 🙂 I'm unsure what you mean by an 'Android control', but unfortunately, I'm not very experienced with Android+Unity development and wouldn't feel comfortable providing information or guidance on that topic unless it relates to a specific issue you're having regarding these tutorials. Best of luck to you!
Why did you make a singleton class when you could've just made a script with a static class in it?
hero
Awesome tutorial but very fast!
Don't know if anyone is having this problem but calling loadGame() in OnSceneLoaded give massive errors in Builts, you have to wait a second bebfore calling the Methods. Don't know why tho.
Im having some troubles. I only have one other scene that the player can actually play and I want to reload the scene when he dies or chooses to. But the problem is, that the saved gameData is not getting reset when I call the NewGame(); function. Anybody know how I can fix it?
Hey there! Unfortunately, I'm not sure if I have enough info to give solid direction on a fix - but here's how I would start with troubleshooting.
Put Debug.Log(..) statements in your NewGame(), LoadGame(), and SaveGame() methods to ensure they're getting called when you think they are. There's a good chance it either (1) NewGame() might not be getting called at the right time or (2) the call to NewGame() getting overwritten by a call to LoadGame() or in some other way.
If that's the case, be sure to call SaveGame() after starting a NewGame() so that it properly overwrites your saved data with New Game data.
I hope that helps a bit and best of luck to you! 🙂
@@ShapedByRainStudios I have a related question: when I try to load a new game i get all of my data related to items collected reset, but my simpler data (health, and player position) do not get reset. I tried debugging, as suggested above, and explicitly put a SaveGame() call immediately after my NewGame() call, but still not luck. Any ideas?
I have copied the tutorial perfectly, but what happens is that when I press "new game" my player puts in the wrong position. It is put in the (0,0,0). How can I make it go where I want it?
Hey! 🙂 When you start a 'New Game' - the data defaults to what's in your GameData constructor method. In these tutorials, we used Vector2.zero which will start the player at (0,0). If you want the player to start at something other than that, you'll just need to change it in that GameData constructor like so - _playerPosition = new Vector2(20, 54);_
@@ShapedByRainStudios Thank you for the answer. Finaly I managed to do it. Im new in unity
Can someone help me, i dont understand how i can load from the level where i was last
Hello, I'm experienced some errors like didn't detect the interactable code in newGameButton.interactable = false; continueGameButton.interactable = false; Even the Using UnityEngine.UI; how can I do it? I hope it helps. Thank you from Philippines
Hey there! 🙂 It's difficult to give solid troubleshooting steps based on the info provided, but here are a couple things that come to mind you can check.
1. Restart Unity and your Code Editor. When you launch the code editor, also make sure you launch it through Unity by opening a Script there.
2. Ensure that the buttons are declared in that script and are the correct variable type (see that section of the video).
Best of luck!
Thankss
I have an issue and I can't find the problem.
Basically my OnEnabled() is never being called (OnDisabled() as well). Can someone help me out here?
found the error after 13 hours... was calling OnEnabled() instead of OnEnable() lol I'm going to kill myself
I know that no one cares but I was first!
Mango
@@luisrosado7050 Tahiti
Thanks for posting these videos. I'm currently having a problem that I couldn't find a solution to in the Bug Fixes video. These following lines have been giving me errors.
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded();
SceneManager.sceneUnloaded += OnSceneUnloaded();
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded();
SceneManager.sceneUnloaded -= OnSceneUnloaded();
}/**/
public void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{}
public void OnSceneUnloaded(Scene scene)
{}
Any ideas on how to fix this?
Do you think this is because I'm using the wrong version of Unity? (I'm using 2019.4)
(error CS0029: Cannot implicitly convert type 'void' to 'UnityEngine.Events.UnityAction)
(error CS7036: There is no argument given that corresponds to the required formal parameter 'scene' of 'DataPersistenceManager.OnSceneUnloaded(Scene))
Hello Schoenhoff Studios. Try to spot the difference.
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.sceneUnloaded -= OnSceneUnloaded;
}/**/