Hey everyone! SInce making this video, Microsoft have recommended not using the Binary Formatter for security reasons. Which you can read about here: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide I'm keeping the video up because the overall content is still relevant, *but* I suggest looking at the XML/DataContractSerializer as the method for storing your data instead. The info of which can be found here -> docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer?view=net-5.0 Your overall approach should be roughly the same with one of the other serialization methods, so hopefully there's still something useful you can grab from the video. - Matt.
I'm having a very hard time seeing the security risk for the case you're illustrating here. The risk takes place when data is transmitted between machines (Eg: the internet) as far as I can tell. The closest I can see a Unity game coming to having this risk is if it's saving/loading data across a cloud platform (Eg: Steam). For a multiplayer/onine game, this would be a huge problem. But for a game that only saves and loads data from the computer it's installed on, it seems the Binary Formatter should be completely fine. And even if someone hacked a remote save file, isn't the worst they could do be to ruin your game data? Please anyone let me know if I'm missing something and there's a way this could open up someone to a Trojan or other hazard. I'm definitely not a hacker or security expert. Edit: I did find this useful example of how it could be abused. Apparently a blob that couldn't be deserialized still has a dispose() method called on it which can execute malicious code, including file deletion commands.
Any chance for a 2021 remake of this video using XML/DataContractSerializer? Loved the toy example, great way to teach saving prefabs and its instanced positions for base building projects!
@@UrbanArT69 I've since gone back and used the BinaryReader and BinaryWriter. You can use it to read/write a raw string from/to a file. Once you do that, you can deserialize the string into your Serialized objects using the JSON utility with Unity. Not sure yet on performance as I'm still just on POC. This also means all the objects you already serialized before stay exactly the same (in theory). You're just using the JSON utility instead of the Binary Formatter to read the data into the objects.
As far as I understand about security, binary seems more secured for me since the data inside the saved file is in binary state. XML is more human readable, easier to be changed. Am I wrong ? I realy don't see the security issue here :(
@@alextreme98 The issue is that the Binary Formatter executes a dispose method on any object whether it can successfully deserialize it or not. Hackers can create data objects that contain exploitative code in the dispose logic that gets run when you try (and fail) to parse the data. It's not really an issue except in network IT. But then, I'm always surprised by how hackers find exploits in infrastructure in the first place. Practically speaking, even if you had a single player game that only saved/loaded from your local HD, if you were to publish your game on Steam and use its cloud storage, and someone were able to hack Steam and modify the save files there, they could use your game to execute malicious code via your remotely saved and corrupted data. It's pretty far-fetched IMO, but still. If I were a new programmer who just wanted results, I'd go ahead with the Binary Formatter anyway. It's quick and easy to get running. You can address security concerns later during development after you have a functional prototype. And if you do switch to a more secure save system, all the classes you've marked [Serializable] will basically be the same if you use JSON instead (which is what I recommend). HTH
For anybody having the error "Property or indexer 'SaveData.current' cannot be assigned to -- it is read only", this may offer a solution. In your SaveData class you should currently have the code below: private static SaveData _current; public static SaveData current { get { if(_current == null) { _current = new SaveData(); } return _current; } } Below is an edited version of that, which allows this to have a value assigned to it, which is what we are doing when loading. private static SaveData _current; public static SaveData current { get { if(_current == null) { _current = new SaveData(); } return _current; } set { if(value != null) { _current = value; } } } And also make sure that the SaveData class has [System.Serializable] above it. This should hopefully fix the problem.
I guess Binary Serialization only works for windows systems. I'd personally use XML or JSON serialization. Pretty much the same amount of code, but more universal.
Oh boy! I'm embarrassed to admit I didn't watch the entire episode for I already have my own save system implemented. But it was pure gold what I missed. Back then I already liked but for anyone there reading this is the best saving system tutorial in unity. Thanks for sharing!
Just dropping a comment to tell you the videos are amazing. I had never heard of the surrogates until I saw this video. I love that you don't hold your viewer's hand, and instead explain quickly and concisely what you're doing and how you go about it.
if anyone wants to go above and beyond, I suggest, during the saving process the system should take a snapshot of the current view of the gameplay and save it along with the file. That way, the player can have a screenshot of the state of the save in the menu.
This topic needs a revisit I think. I've spent the last 2 weeks trying to get this to work & have with varying degrees of success for how I wanted it Implemented. After doing my own research there's actually huge chunks of info in this that are skipped over & just not mentioned in order to get it to work/understand it's limitations. I get the idea behind getting viewers to do their own research & learning how to do it on their own, but I think this video is a step to far beyond that and needs to include a few more steps for it to be a tutorial people can actually follow along.
hey, can you give more information about the things he skipped please ? With only his tutorial, I've managed to do what I wanted to do for my (simple) project. idk if I've missed something tho
@@Nicoblabla one thing he skipped was an event manager that he created off camera without telling us, which was used in the toyhandler script. The people who didn't know this would not have their save system work.
There is also another reason this topic needs a revisit. Even though this is a great tutorial and a great way introduction to the saving system. The binary format is not safe to use and it is easy to hack and make consumer load virus and malware. Even Microsoft actively encourages you to remove it from your games. But thanks to this tutorial, I actually had to do some reason on my own and came across this article. Source: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide So also think a revisit would be a good thing, so people don't make their first game, filled with security threats.
Just stopping by to say that your video is the only tutorial on saves that deals with objects in a scene and thus, the interesting parts of the whole thing. Nice work.
Thank you for sharing your system. I'm just starting out learning Unity and this is the first "system" I've implemented in the game I'm tinkering with. It took me a whole day to get your system working but I see now I've made the right decision in following your solution. Everything updates itself automatically !! Wow, I wasn't actually expecting that when I started, but its turned out fantastic. Thank you :)
With this video i realize that in my game if you die you will never start on a saved level XD . Its hard to make a save system. But the video is awesome men ! You are great Thanks!
you and Jason Weimann along with some others have the best unity videos . I want to be able to come up with system like these .this video and the one with tab system helped me a lot
Awesome guides! Built my first save/load system in a similar fashion but this has some improvements my uses arguments to change obj and casting. Like the short conciseness and the speed up of code of your presenting style. Keep it up dude
dude! your tutorials are pretty useful and straightforward. Also, you always try to code in the standard way which makes it reliable. ;) please create more!
you actually covered shit that would be an actual concern for a game that's not just a mindless smartphone game - you talk about saving/loading gameobjects and states regarding those game objects, and even go the extra mile of covering the concept of multiple save slots. Very useful.
very great video everything seems professional the only problem is that sometimes its hard to follow what you are doing sometimes there are not enough explanation and your pace is too fast for people who are starting to learn
Love the tutorial, it seems like a great save system. Can you please upload the missing steps to really follow along what you do in the video, it's impossible to do so.
Hey ! Amazing tutorial BUT, I have a problem at 7:26 with you're 25 line which is the SaveData.current, my code told me that this variable is on read only :/ How did you patch this ? What's on the top of the ToyManager script and the GameEvents ? You don't show them. Thx for help
Hey! i get an error on line: GameObject obj = Instantiate(toys[(int)currentPlayerData.objectType]); cannot find the name "toys", where is that from? Thanks for your response
This is a very informative video and I picked up some things that I can use. However, watching the video is like starting a book and realizing that some key chapters are missing. I understand that this is an intermediate guide covering some underlying concepts for developing a save system, but referencing objects and classes that are not discussed is inconsistent with the video title in my opinion. The title of the video "How to Build A Save System in Unity" should read "Tips and Tricks for Building a Save System in Unity"
Having recently written some serialization in C++ it looks like way more boiler platey in C#. As long as you don't have any pointers or references in your class it's just: std::ofstream file("savename", std::ofstream::out | std::ofstream::binary); file.write(reinterpret_cast(&save), sizeof(save)); file.close();
At 4:44 you've got a few functions recording the data based on a button press. If I have a bunch of thing I need to keep track of (like what what the player's stats are, what's in their inventory list, what story triggers they've been through etc.) would I need to use separate functions for all those things? I kind of just want to save everything about the player all at once (my game is text based).
This is what the GameData class is for. As discussed in the video. If you put everything you need to save in a single serialised class such as GameData you can just save that GameData class. If you've got classes all over the place with data you need to save, I would either refactor it so the saved data is in one place OR write methods to call to those classes and pass the data on save/load accordingly.
Hi, i really like your tutorial. Thank you it was so helpful. Is there any chance that you upload the codes or project to github? Because i think i m doing something wrong.
Another great video! PlayerPrefs is incredibility slow and I I've done JSON before prefixed with a salted hash. I touched the binary formatter before in a sample project but never went in depth, I'll give it another look. Thanks for the vid!
Amazing video! One small question. I think 'toys' is a collection of gameObjects of all the prefabs. How do you go about creating the toys collection in the code?
I'm a beginner and i have a fair question. On a certain point of the video he uses the save button which was not ever mentioned how in the heck it was scripted. so how could i script the save button so it actually updates the data that i will load pressing the load button.
Hey! Hope This Helps! ----------------------------------------------------------------------------------------------------------------------------------------------------------- public void OnLoadGame() { //this is the load function assign this to the load button SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save"); } public void OnSaveGame() { //This is the save function, "Save" is the name of the save file, and save data is the object from the script in the video, assign this to the save button. SerializationManager.Save("Save", SaveData.current); } -Chris
@@danielmakac583 put t n save data and then you can call t from another script if needed. I think you can do public SaveData saveData; and then when you need the save method to be called saveData.Save or Load not sure this was long ago.
Does anyone know what is the "toys" list that is being used while Instantiating at 7:26 ?? :( Is it something declared in this class again? I am not able to progress after this step!
Could you provide the source code in the description for vids like this? You kind of breezed past writing the actual save and load functions and as a beginner it left me very lost. Being able to look back on all your code would help a lot.
Yea he needs to redo this video and make it better. so much is missing. Very hard to understand if your new and if your not new no need to watch it because your skills are beyond this.
public void OnLoadGame() { SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save"); } This line gives out an error when I put it in any script and says can't assign current cause its read only? can you help me with that? I did get rid of the error by adding a set method after get so setting current = value; not sure if this is the correct way of doing it but it got rid of the error.
hello, I have a GTA style project. I am looking for the Save Load system, you have made the purchase part in the save load window you wrote, but I want the player to continue from where it left off by pressing the Load button registered in the load section. What kind of way should I follow?
I am confused, at 3:32 you created the SaveData as a singleton, with _current, but after, at 4:54 at current can be assigned, 5:37, _current no longer exists. :?
Hi i'm getting an error when i try to implement this code (first half of the video) I get a "NullReferenceException: object reference not set to an instance of an object" when i try to refer to the save data. So im trying to add to the save data: SaveData.current.profile.partyNames.Add("Blah"); but i get that error. do i need to do something like, resources.load or have the SaveData script attached to something and referance that object? Im not sure if ive missed something in your video or? Cheers
I have no idea what i've done wrong or what he's done that he's not shown. I've followed his code exactly up to the 5 minute mark. Did anyone else have this issue? I just cant seem to access the data, for example: SaveData.current.profile.currency -= 200; results in the error i've mentioned above. So is he referancing the class in some way he's not shown or what? is that code he's doing in a specific script? (PlayerProfile, SaveData, SerilizedManager) does anyone know whats happening here as im pulling my hair out trying to get it to work.
Great Question. So, the fields that haven't changed will still load correctly - even if you've changed the structure of the class. (I actually used the same save data file here for the two versions) It just didn't assign the old data anywhere because it no longer existed. What I tend to do, is add a string field into the save data that tracks the version of the game. Then, when the game loads depending on what I've changed between versions I'll either try to parse that data, or replace it with the new data / fields instead. It's really up to you how you handle dealing with changed fields though. It'll be a bespoke solution depending on your project structure, but I'd suggest starting by tagging each save with a version and doing some kind of comparison on load.
how do i implement the PlayerProfile non Monobehavior class on SaveData? everytime i try to access or change 'profile' variables, the script trying the access returns that this class is null. i tried instantiating it in many diferent ways but that interferes with saving the data or just plainly don't work. what has he done here to make his work flawlessly? i have not done anything diferent. has he added extra code to Profile or something that he didn't show?
The ToyHandler script throws a NullReferenceException: Object reference not set to an instance of an object. This error is from the SaveData.current.toys.Add(toyData) line. I don´t know how to fix it :(
@@teilzeit_deutsch582 I have been pulling my hair out. I am not sure why the game just won't save. I keep getting this error: NullReferenceException: Object reference not set to an instance of an object When trying to set SaveData.current.profile.characterSelection = PlayerPrefs.GetInt("CharacterSelected", characterSelection); I have even set the variables in the SaveData with no luck
How is the save function being called? I have the save button linked to public void SaveGame() { // Set data SetSaveData(); Debug.Log("Save is pressed: Game is -" + saveName.text); // Save the game SerializationManager.Save(saveName.text, SaveData.current); } The savedata is the above function I wrote to set the data.
Underrated! Me: sitting and codding universal save system that will save any stuff in any way and load any stuff in any way. When i saw this video i was like: "What a fuck! Well it's not bad, but it's not cool to be called SAVE SYSTEM". Well, the thing that pretend to be a save system must next feature: save any anything, and load anything with no inside code reworks
@@mutlugameofhalit if you write New Classes for saving in frame of your save framework, its possible yes. Its mean use attributes and decorates class code with them. After that you can just do this any time you need data from or in you save: SaveService.GetEntry(playerid).AddItems(goldid, 150). And its will be automatically change in save. So in term of acessing Inventory data you can just use entry and dont use other Classes inside gameplay loop. InventoryEntry.GetItemCount(itemid). Simple and easy, no need to use separate Inventory data code presentation for saves and gameplay
Hello, I'm very beginning in c# (and programmation in general), so I don't understand everything in this tutorial, so I don't really understand how it works, to save do I have to put all the variables I want to save in save data (from all objects I have) or I have to create a SaveData script for each object?
If you were to do an open world save system, how would you save/load/unload data with additive scene loading? Would you add an int for the scene index of each object and only load if the matching scene is loaded? Would the save function work modularly?
So, I would keep the game state data independent from any scene. That way all the save data for your game would be serialised no matter what scene you're in. But, if you need to serialise chunks of data for each scene, such as object positions, or specific world changes, etc.. you could create a list of game data classes and save/load each item in that list for each scene index. When a scene loads, you could query the master game state and ask for the save data for that scene.
Game Dev Guide I’m not sure I completely understand. So if I had scene A and B and I wanted to save scene A’s data list when I move to scene B, would I save scene A’s list, load and delete scene B’s list and then save scene B’s list when I need to? Or would I only save scene At list then load scene B’s list and then save it when I need to? Would it automatically overwrite or just add onto the previously saved scene B list? Perhaps a video would help me more, I’m having trouble working this out in my head 😅
@@CamNicPet CamNicPet Everything you need to know is already covered in this video in regards to saving and loading classes. But, it sounds like you're unsure how references and lists/arrays work. I'll try to clarify, my approach to this I would be to have a Game Data class that holds all of the data in my game I want to save. This would not be tied to any scene, which means that it can be accessed anywhere and hold all of the data for your game. (This is shown in the video) Inside my GameData class, I would probably have a list/array of a LevelData class which would hold level specific data I need to store. Any scene I have in my game would require a reference to a LevelData class. So, when I load a scene, I just get the coresponding LevelData class from the list of them in my GameData class. If I were to reference and retrieve the LevelData from my GameData class, any changes I make to the LevelData when my scene is loaded would actually be made in the GameData class due to it being a reference. So when I save my GameData Class, it saves all of my level data too.
hay, I am having an error and I don't know why. When i try to make the Load system you showed "SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save");" I get this error Severity Code Description Project File Line Suppression State Error CS0200 Property or indexer 'SaveData.current' cannot be assigned to -- it is read only Assembly-CSharp E:\Unity\games\ObjectFighters\Assets\Scrips\SaveSystem\SaveData.cs 26 Active Can you help me?
The error is in the SaveData current method, here put this: get { if (_current == null) _current = new SaveData(); return _current; } set { if (value != null) _current = value; }
Nice and well made tutorial, thanks! How would you handle loading saves from different versions of the game? For example, if you have removed a unit/building that is in a save, or perhaps added new properties to something existing. Also, it would be really cool to see your approach on a replay system, e.g. replaying a full match/game (like Starcraft) or just recording a sequence of a game for review later.
old question but, you can have a version number on save files so when you change something in save, you change version number and keep old version readers all the time if u want to have backward compatibility.
good but can i use binary format file ,to be stored in database like Mysql or Mongodb , so the player can keep his game persistent despite changing the devices , which file format and database do you recommend
I feel like these serialization surrogates are harder then it should be. Looking at it, it makes sense, but you can just as well store a Vector3 as 3 separate floats without this surrogate method, imo that's faster and easier to read.
It does feel like he could add 1 minute to the video and have everything explained in full... This tutorial is written for a very small margin of people, it's kinda mind boggling lol. I understand a good chunk of it, but there's so much just randomly left out, for unexplained reasons. For example, right off the bat, in the first 3 minutes he adds some name spaces, doesn't mention it at all, for a noob it's kinda difficult to follow along.
Hi! great tutorial. I have two questions: - Why SaveData from 5:37 is diferent from 3:19, regarding lines 6 and 7 (the _current and current thing)? I'm assuming the singleton does not work or is related with my next question... and - How did you solved the error "Object reference not set to an instance of an object" when trying to access current.profile...? Thank you.
Sorry. I didn't tell you how I got the error: The error hapens running the "Work" from 4:41 , line 44. I can change the toy count, save it and load, retriving the correct values but the variables inside the other class (PlayerProfile) I can not.
@@CyberStudios Yep!... If I remember correctly, but... don't remember how. Anyway, after one week of crying and banging my head against the wall I was able to figure out a solution... Here you have the scripts I use... try to make sense of them because I really don't remember how... drive.google.com/file/d/17EovyHDCkgzvTsIy68GXtcSHT8fbzz1B/view?usp=sharing
When SaveData.current can't be assigned a value because it's read only just add the following below the body of the get statement in the SaveData class's singleton: set { _current = value; } It worked for me... I think😊
Hey, would you mind helping? I am getting a non instance of object, when using the current.profile.characterName. I am not sure how this is null? How does one set data then?
I want to use this system to store the data on the amazon s3 bucket , for all my players game state , but the really problem that is bothering me , what if I want to add new features to my game , how shall the file schema change can be implemented upon the existing binary files , plz reply
you are going the change the class implementation, if the binarydata does not have this property to set, it will set as default value, so in that case you need to set your default value or keep it as default of the value/reference type. so keep implementing :)
This seemed like a great tutorial before I actually tried to implement it. Watched through the video once, yeah I understood everything, so decided to follow along. Nope... it turns out there are critical pieces missing from this tutorial right before you build the UI. I followed up to this point, and don't understand how the saving is working when you press the save button. Can't progress any further due to errors with the load path and SaveData instancing. Looks like wasted time, unfortunately. I recommend on this one you go back through your video following along to see where you have missed these key components. I've followed a few of your other videos very easily to completion, so it looks like you just missed a key explanation here.
if it's any use I quickly made a bare-bones example of how to use it, but instead of cars and dolls I've used coins and notes. I hope this helps you understand how it works public void SaveProgress() { SaveData.current.coins = coins; SaveData.current.notes = notes; SerializationManager.Save("example", SaveData.current); } public void LoadProgress() { SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/example.save"); coins = SaveData.current.coins; notes = SaveData.current.notes; }
I belive he rasies a GameEvent OnLoad and Onsave, that all objects that can be saved/loaded can subscribe to. See his previous making custom event videos on how it works and how to raise one
@@81gamer81 how the hell does he instances 'PlayerProfile'? everytime i try to access profile from SaveData.current.profile it gives me that the thing doesn't exist! instantiating it also doesn't work, whatahell did he do??? i hate this so much!
It should work across all platforms. It should also behave as expected for newer versions of your savedata class - it will still deserialase the existing (older) properties into a newer version of the savedata class, but new properties would need to be handled/initialised when loading.
Hi so i know that this is older but would you make now multiple methods in your Serialization Manager for different scripts that your trying to serialize like I have a player and weapons. So i have made SavePlayer and SaveWeapons, Along with the load methods... Does this make sense? Thanks!
He mentions everything you need to know in order to do that. You want to save weapons? give them all ID numbers and save those. the player? save it's stats and position as ints and vector3's into the SaveData file.
What if you wanted to save a list of items and save it outside of the persistent data path? Say you wanted to set up a store and you saved all your items in a list, then the store would load the binary file when you entered?
It tells me that The name 'loadArea' does not exist in the current context. But I can't seem to see any reference to a "loadArea" in the SaveManager script in the video. Is there a reference? if so what is the reference?
The ideas here are quite useful but you should never use a binary formatter for save games as that can be used by hackers as an attack vector against your QA in the form of maliciously edited save files. More details can be found in the MSDN docs about the binary formatter describing how it cannot be made safe and why it wouldn't be used for this purpose.
Yep, at the time the video went out this wasn't a known issue, however since the MSDN Docs have been updated the pinned comment explains the update. I'll eventually walk through an alternative in another video, but the underlying concepts for the system are still the same -- you'll just need to use one of the different serialisation methods.
@@GameDevGuide Well i was blind for certain hah, completely glossed over that. You have it covered there certainly (though i would if you can bother add a video sticker at start etc)
"If you found anything useful in the video" Me: All of it!!. Playerprefs starts to become a real mess, real fast. It's like that draw or cupboard you have in your house, you know, the one full of junk that you don't even want to spend more than 20 seconds looking in LOL.
Great video! Question: suppose you were making something a bit more complex where you wanted more types of objects with their own savable data (say a RTS game or RPG). Which approach would you go with for the ToyData class? 1-Make one universal ToyData class that holds all the data you might ever want to save 2-Make subclasses of ToyData with their own additional data, possibly making use of interfaces for accessing data 3-Make ToyData into an Entity style class that is mostly empty but can hold components that are accessed with generic GetComponent function All of these have pros and cons...1 is potentially clunky if you need to add more data, but is also the simplest and fastest. 2 runs into the issue of inheritance vs composition. 3 has composition, but that also means accessing the components may have a performance cost, plus you now need to worry about the actual composition (might need to make factory classes for example).
Hey everyone! SInce making this video, Microsoft have recommended not using the Binary Formatter for security reasons. Which you can read about here: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide
I'm keeping the video up because the overall content is still relevant, *but* I suggest looking at the XML/DataContractSerializer as the method for storing your data instead. The info of which can be found here -> docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer?view=net-5.0
Your overall approach should be roughly the same with one of the other serialization methods, so hopefully there's still something useful you can grab from the video.
- Matt.
I'm having a very hard time seeing the security risk for the case you're illustrating here. The risk takes place when data is transmitted between machines (Eg: the internet) as far as I can tell. The closest I can see a Unity game coming to having this risk is if it's saving/loading data across a cloud platform (Eg: Steam). For a multiplayer/onine game, this would be a huge problem. But for a game that only saves and loads data from the computer it's installed on, it seems the Binary Formatter should be completely fine. And even if someone hacked a remote save file, isn't the worst they could do be to ruin your game data? Please anyone let me know if I'm missing something and there's a way this could open up someone to a Trojan or other hazard. I'm definitely not a hacker or security expert. Edit: I did find this useful example of how it could be abused. Apparently a blob that couldn't be deserialized still has a dispose() method called on it which can execute malicious code, including file deletion commands.
Any chance for a 2021 remake of this video using XML/DataContractSerializer? Loved the toy example, great way to teach saving prefabs and its instanced positions for base building projects!
@@UrbanArT69 I've since gone back and used the BinaryReader and BinaryWriter. You can use it to read/write a raw string from/to a file. Once you do that, you can deserialize the string into your Serialized objects using the JSON utility with Unity. Not sure yet on performance as I'm still just on POC. This also means all the objects you already serialized before stay exactly the same (in theory). You're just using the JSON utility instead of the Binary Formatter to read the data into the objects.
As far as I understand about security, binary seems more secured for me since the data inside the saved file is in binary state. XML is more human readable, easier to be changed. Am I wrong ? I realy don't see the security issue here :(
@@alextreme98 The issue is that the Binary Formatter executes a dispose method on any object whether it can successfully deserialize it or not. Hackers can create data objects that contain exploitative code in the dispose logic that gets run when you try (and fail) to parse the data. It's not really an issue except in network IT. But then, I'm always surprised by how hackers find exploits in infrastructure in the first place. Practically speaking, even if you had a single player game that only saved/loaded from your local HD, if you were to publish your game on Steam and use its cloud storage, and someone were able to hack Steam and modify the save files there, they could use your game to execute malicious code via your remotely saved and corrupted data. It's pretty far-fetched IMO, but still. If I were a new programmer who just wanted results, I'd go ahead with the Binary Formatter anyway. It's quick and easy to get running. You can address security concerns later during development after you have a functional prototype. And if you do switch to a more secure save system, all the classes you've marked [Serializable] will basically be the same if you use JSON instead (which is what I recommend). HTH
For anybody having the error "Property or indexer 'SaveData.current' cannot be assigned to -- it is read only", this may offer a solution.
In your SaveData class you should currently have the code below:
private static SaveData _current;
public static SaveData current
{
get
{
if(_current == null)
{
_current = new SaveData();
}
return _current;
}
}
Below is an edited version of that, which allows this to have a value assigned to it, which is what we are doing when loading.
private static SaveData _current;
public static SaveData current
{
get
{
if(_current == null)
{
_current = new SaveData();
}
return _current;
}
set
{
if(value != null)
{
_current = value;
}
}
}
And also make sure that the SaveData class has [System.Serializable] above it.
This should hopefully fix the problem.
THANK YOU, this is a blessing!
Thank you !! I knew someone would come thru in the comments :)
THANK YOU SO MUCH
why the hell didn't he do that in the tutorial man, jesus. this is so lackluster, he leaves that part unfinished and shows it working just fine!
thanks
One of the best save system tutorial I've watched.
Straightforward and Concise.
Good job
I guess Binary Serialization only works for windows systems. I'd personally use XML or JSON serialization. Pretty much the same amount of code, but more universal.
@@neeeeeck9005 Binary serialization works for any platform. JSON is certainly less universal than a simple binary file.
How is it in any way concise? It skips over far to much.
@Blackstorm JSON and XML are way more unsecure too cuz u can very easely modify the code
Oh boy! I'm embarrassed to admit I didn't watch the entire episode for I already have my own save system implemented. But it was pure gold what I missed. Back then I already liked but for anyone there reading this is the best saving system tutorial in unity.
Thanks for sharing!
Just dropping a comment to tell you the videos are amazing. I had never heard of the surrogates until I saw this video. I love that you don't hold your viewer's hand, and instead explain quickly and concisely what you're doing and how you go about it.
if anyone wants to go above and beyond, I suggest, during the saving process the system should take a snapshot of the current view of the gameplay and save it along with the file. That way, the player can have a screenshot of the state of the save in the menu.
Good thinking
This topic needs a revisit I think. I've spent the last 2 weeks trying to get this to work & have with varying degrees of success for how I wanted it Implemented. After doing my own research there's actually huge chunks of info in this that are skipped over & just not mentioned in order to get it to work/understand it's limitations. I get the idea behind getting viewers to do their own research & learning how to do it on their own, but I think this video is a step to far beyond that and needs to include a few more steps for it to be a tutorial people can actually follow along.
hey, can you give more information about the things he skipped please ?
With only his tutorial, I've managed to do what I wanted to do for my (simple) project. idk if I've missed something tho
@@Nicoblabla one thing he skipped was an event manager that he created off camera without telling us, which was used in the toyhandler script. The people who didn't know this would not have their save system work.
There is also another reason this topic needs a revisit. Even though this is a great tutorial and a great way introduction to the saving system. The binary format is not safe to use and it is easy to hack and make consumer load virus and malware. Even Microsoft actively encourages you to remove it from your games. But thanks to this tutorial, I actually had to do some reason on my own and came across this article.
Source: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide
So also think a revisit would be a good thing, so people don't make their first game, filled with security threats.
@@chazzwazzler
Is there someone who can solve this problem?
Your tutorials are really straight forward and not those 50 minute videos, which explain useless stuff. Thank you so much for making these.
Just stopping by to say that your video is the only tutorial on saves that deals with objects in a scene and thus, the interesting parts of the whole thing. Nice work.
Greatest Unity save load tutorial video I can find. Thanks!
Would love to see you do a dialog system!
Yeah
That is so easy to do, and u don't need code, I'll have a vid on that soon!
Thank you for sharing your system.
I'm just starting out learning Unity and this is the first "system" I've implemented in the game I'm tinkering with. It took me a whole day to get your system working but I see now I've made the right decision in following your solution. Everything updates itself automatically !! Wow, I wasn't actually expecting that when I started, but its turned out fantastic. Thank you :)
This is exactly the sort of more intermediate channel I was looking for.
With this video i realize that in my game if you die you will never start on a saved level XD . Its hard to make a save system. But the video is awesome men ! You are great Thanks!
Hey there, I just wanted to say I love your funny, straight to the point videos. You deserve a lot more subscribers! Keep being awesome.
First minute of watching: why am I not subscribed to you? This is gold!
you and Jason Weimann along with some others have the best unity videos . I want to be able to come up with system like these .this video and the one with tab system helped me a lot
Awesome guides! Built my first save/load system in a similar fashion but this has some improvements my uses arguments to change obj and casting. Like the short conciseness and the speed up of code of your presenting style. Keep it up dude
This is so helpful. I learned file systems at my university but it was in C++ and I have had trouble learning how C# does it.
Your videos are so underrated
just 100% what I need atm. I wanted to save positions of spawned objects and you just shown me how to do that! subscribed!
dude! your tutorials are pretty useful and straightforward. Also, you always try to code in the standard way which makes it reliable. ;)
please create more!
you actually covered shit that would be an actual concern for a game that's not just a mindless smartphone game - you talk about saving/loading gameobjects and states regarding those game objects, and even go the extra mile of covering the concept of multiple save slots. Very useful.
OMG. This is what I've been looking for for a whole month. Really appreciate your channel. Thank you.
This is one of the most useful unity tutorial channel I ever found ! Thanks, I learn a lot with your videos !
very great video everything seems professional the only problem is that sometimes its hard to follow what you are doing sometimes there are not enough explanation and your pace is too fast for people who are starting to learn
Love the tutorial, it seems like a great save system. Can you please upload the missing steps to really follow along what you do in the video, it's impossible to do so.
this was by far the most helpful thing I have found yet, thank you so much.
Awesome, thank you! I saw something similar years ago and I've been searching for another guide. Great job!
Hey ! Amazing tutorial BUT, I have a problem at 7:26 with you're 25 line which is the SaveData.current, my code told me that this variable is on read only :/ How did you patch this ? What's on the top of the ToyManager script and the GameEvents ? You don't show them. Thx for help
same, kind of makes it hard to follow along and take notes when a key part of the system isn't there
You'll need to make a reference to it
@@terdell thank you very much ;-)
@@patrevizani hey, can you help me? What did you do?
@@terdell You saved me dude!
extremely excellent storage system .The option to save multiple files :) Thank you I have been looking for something like this . Excellent video!
Use Path.Combine because different operating systems use different seperators.
Very nice tutorial! I did learn a few new concepts and even though I am not using unity they seem pretty universal concepts.
Hey! i get an error on line: GameObject obj = Instantiate(toys[(int)currentPlayerData.objectType]);
cannot find the name "toys", where is that from? Thanks for your response
he created a GameObject array of his prefabs called "toys" which also drove me mad trying to figure out since he does not explain that he did it.
@@IsaiahC86 where did he create him? In SaveData or in ToyData?
This is a very informative video and I picked up some things that I can use. However, watching the video is like starting a book and realizing that some key chapters are missing. I understand that this is an intermediate guide covering some underlying concepts for developing a save system, but referencing objects and classes that are not discussed is inconsistent with the video title in my opinion. The title of the video "How to Build A Save System in Unity" should read "Tips and Tricks for Building a Save System in Unity"
Having recently written some serialization in C++ it looks like way more boiler platey in C#. As long as you don't have any pointers or references in your class it's just:
std::ofstream file("savename", std::ofstream::out | std::ofstream::binary);
file.write(reinterpret_cast(&save), sizeof(save));
file.close();
At 4:44 you've got a few functions recording the data based on a button press. If I have a bunch of thing I need to keep track of (like what what the player's stats are, what's in their inventory list, what story triggers they've been through etc.) would I need to use separate functions for all those things? I kind of just want to save everything about the player all at once (my game is text based).
This is what the GameData class is for. As discussed in the video. If you put everything you need to save in a single serialised class such as GameData you can just save that GameData class.
If you've got classes all over the place with data you need to save, I would either refactor it so the saved data is in one place OR write methods to call to those classes and pass the data on save/load accordingly.
@@GameDevGuide Okay thanks that makes sense!
Hi, i really like your tutorial. Thank you it was so helpful. Is there any chance that you upload the codes or project to github? Because i think i m doing something wrong.
Another great video! PlayerPrefs is incredibility slow and I I've done JSON before prefixed with a salted hash. I touched the binary formatter before in a sample project but never went in depth, I'll give it another look. Thanks for the vid!
Amazing video! One small question. I think 'toys' is a collection of gameObjects of all the prefabs. How do you go about creating the toys collection in the code?
Thank you! Finally found what I was exactly looking for!
I'm a beginner and i have a fair question.
On a certain point of the video he uses the save button which was not ever mentioned how in the heck it was scripted.
so how could i script the save button so it actually updates the data that i will load pressing the load button.
Hey! Hope This Helps!
-----------------------------------------------------------------------------------------------------------------------------------------------------------
public void OnLoadGame()
{
//this is the load function assign this to the load button
SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save");
}
public void OnSaveGame()
{
//This is the save function, "Save" is the name of the save file, and save data is the object from the script in the video, assign this to the save button.
SerializationManager.Save("Save", SaveData.current);
}
-Chris
@@kristerskarklins4722 where do i place this ? is this inside the SaveData class or can be anywhere else or in the different class?
@@danielmakac583 put t n save data and then you can call t from another script if needed.
I think you can do
public SaveData saveData;
and then when you need the save method to be called
saveData.Save or Load not sure this was long ago.
@@kristerskarklins4722 yeah i did. I eventaully it figured hahaha. but thanks for replying
Perfect tutorial .
subscribed in a minute.
Thanks for this. I never knew there're binary surrogates class
Does anyone know what is the "toys" list that is being used while Instantiating at 7:26 ?? :( Is it something declared in this class again? I am not able to progress after this step!
Could you provide the source code in the description for vids like this? You kind of breezed past writing the actual save and load functions and as a beginner it left me very lost. Being able to look back on all your code would help a lot.
Yea he needs to redo this video and make it better. so much is missing. Very hard to understand if your new and if your not new no need to watch it because your skills are beyond this.
Fantastic explanation. Cheers pal.
public void OnLoadGame()
{
SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save");
}
This line gives out an error when I put it in any script and says can't assign current cause its read only? can you help me with that?
I did get rid of the error by adding a set method after get so setting current = value;
not sure if this is the correct way of doing it but it got rid of the error.
I've been looking at your tutorials! Great stuff!!
Does this also work for WebGL platform? Like, will the files be stored in the browser cache or machine folder?
hello, I have a GTA style project. I am looking for the Save Load system, you have made the purchase part in the save load window you wrote, but I want the player to continue from where it left off by pressing the Load button registered in the load section. What kind of way should I follow?
What command do you use in the Save button ?
No Set {} in the SaveData ?
I am confused, at 3:32 you created the SaveData as a singleton, with _current, but after, at 4:54 at current can be assigned, 5:37, _current no longer exists. :?
Hi i'm getting an error when i try to implement this code (first half of the video)
I get a "NullReferenceException: object reference not set to an instance of an object"
when i try to refer to the save data.
So im trying to add to the save data:
SaveData.current.profile.partyNames.Add("Blah");
but i get that error. do i need to do something like, resources.load or have the SaveData script attached to something and referance that object? Im not sure if ive missed something in your video or?
Cheers
I have no idea what i've done wrong or what he's done that he's not shown. I've followed his code exactly up to the 5 minute mark. Did anyone else have this issue?
I just cant seem to access the data, for example:
SaveData.current.profile.currency -= 200;
results in the error i've mentioned above. So is he referancing the class in some way he's not shown or what? is that code he's doing in a specific script? (PlayerProfile, SaveData, SerilizedManager)
does anyone know whats happening here as im pulling my hair out trying to get it to work.
@@Rorymclean12 got the same issue with SaveData.current.profile.characterSelection = PlayerPrefs.GetInt("CharacterSelected", characterSelection);
what's going to happen if you make changes to an object and add new fields then try to load an older version?
Great Question.
So, the fields that haven't changed will still load correctly - even if you've changed the structure of the class. (I actually used the same save data file here for the two versions) It just didn't assign the old data anywhere because it no longer existed.
What I tend to do, is add a string field into the save data that tracks the version of the game. Then, when the game loads depending on what I've changed between versions I'll either try to parse that data, or replace it with the new data / fields instead.
It's really up to you how you handle dealing with changed fields though. It'll be a bespoke solution depending on your project structure, but I'd suggest starting by tagging each save with a version and doing some kind of comparison on load.
Well explained, to the point, clear and the example at the end was very helpfull!
Thank you so much! (And the guys improving the code in the comments too)
how do i implement the PlayerProfile non Monobehavior class on SaveData? everytime i try to access or change 'profile' variables, the script trying the access returns that this class is null. i tried instantiating it in many diferent ways but that interferes with saving the data or just plainly don't work. what has he done here to make his work flawlessly? i have not done anything diferent. has he added extra code to Profile or something that he didn't show?
The ToyHandler script throws a NullReferenceException: Object reference not set to an instance of an object. This error is from the SaveData.current.toys.Add(toyData) line. I don´t know how to fix it :(
im sitting in the same boat, but with player profile
@@CyberStudios I fixed my error, i think i could help you
@@teilzeit_deutsch582 I have been pulling my hair out. I am not sure why the game just won't save.
I keep getting this error: NullReferenceException: Object reference not set to an instance of an object
When trying to set SaveData.current.profile.characterSelection = PlayerPrefs.GetInt("CharacterSelected", characterSelection);
I have even set the variables in the SaveData with no luck
How is the save function being called? I have the save button linked to
public void SaveGame()
{
// Set data
SetSaveData();
Debug.Log("Save is pressed: Game is -" + saveName.text);
// Save the game
SerializationManager.Save(saveName.text, SaveData.current);
}
The savedata is the above function I wrote to set the data.
@@CyberStudios i will explain later im not at home at the moment
Thank oyu it6 was very useful. The surogates was totlly new to me. thx! you are great!
PlayerPrefs.SetString("PlayerName", "KillMeNow");
lol
Underrated!
Me: sitting and codding universal save system that will save any stuff in any way and load any stuff in any way. When i saw this video i was like: "What a fuck! Well it's not bad, but it's not cool to be called SAVE SYSTEM". Well, the thing that pretend to be a save system must next feature: save any anything, and load anything with no inside code reworks
@@nikolaynakorkeshko448 is this even possible for different classes? your "the universal save system"?
@@mutlugameofhalit if you write New Classes for saving in frame of your save framework, its possible yes. Its mean use attributes and decorates class code with them. After that you can just do this any time you need data from or in you save: SaveService.GetEntry(playerid).AddItems(goldid, 150). And its will be automatically change in save. So in term of acessing Inventory data you can just use entry and dont use other Classes inside gameplay loop. InventoryEntry.GetItemCount(itemid). Simple and easy, no need to use separate Inventory data code presentation for saves and gameplay
Hello, I'm very beginning in c# (and programmation in general), so I don't understand everything in this tutorial, so I don't really understand how it works, to save do I have to put all the variables I want to save in save data (from all objects I have) or I have to create a SaveData script for each object?
Another games: Some save files saved in documents
Unity games: Where are my save files?
If you were to do an open world save system, how would you save/load/unload data with additive scene loading? Would you add an int for the scene index of each object and only load if the matching scene is loaded? Would the save function work modularly?
So, I would keep the game state data independent from any scene. That way all the save data for your game would be serialised no matter what scene you're in. But, if you need to serialise chunks of data for each scene, such as object positions, or specific world changes, etc.. you could create a list of game data classes and save/load each item in that list for each scene index. When a scene loads, you could query the master game state and ask for the save data for that scene.
Game Dev Guide I’m not sure I completely understand. So if I had scene A and B and I wanted to save scene A’s data list when I move to scene B, would I save scene A’s list, load and delete scene B’s list and then save scene B’s list when I need to?
Or would I only save scene At list then load scene B’s list and then save it when I need to? Would it automatically overwrite or just add onto the previously saved scene B list?
Perhaps a video would help me more, I’m having trouble working this out in my head 😅
@@CamNicPet CamNicPet Everything you need to know is already covered in this video in regards to saving and loading classes. But, it sounds like you're unsure how references and lists/arrays work.
I'll try to clarify, my approach to this I would be to have a Game Data class that holds all of the data in my game I want to save. This would not be tied to any scene, which means that it can be accessed anywhere and hold all of the data for your game. (This is shown in the video)
Inside my GameData class, I would probably have a list/array of a LevelData class which would hold level specific data I need to store.
Any scene I have in my game would require a reference to a LevelData class. So, when I load a scene, I just get the coresponding LevelData class from the list of them in my GameData class.
If I were to reference and retrieve the LevelData from my GameData class, any changes I make to the LevelData when my scene is loaded would actually be made in the GameData class due to it being a reference.
So when I save my GameData Class, it saves all of my level data too.
This video is a piece of cake, love it
thanks you saved my life
hello. will this work when developing a console game. for example would this save system work when building an xbox game? Thanks
How did you assign functions to save and load button? cuz you didn't show it in the video
hay, I am having an error and I don't know why.
When i try to make the Load system you showed
"SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/Save.save");"
I get this error
Severity Code Description Project File Line Suppression State
Error CS0200 Property or indexer 'SaveData.current' cannot be assigned to -- it is read only Assembly-CSharp E:\Unity\games\ObjectFighters\Assets\Scrips\SaveSystem\SaveData.cs 26 Active
Can you help me?
The error is in the SaveData current method, here put this:
get
{
if (_current == null)
_current = new SaveData();
return _current;
}
set
{
if (value != null)
_current = value;
}
Nice and well made tutorial, thanks! How would you handle loading saves from different versions of the game? For example, if you have removed a unit/building that is in a save, or perhaps added new properties to something existing.
Also, it would be really cool to see your approach on a replay system, e.g. replaying a full match/game (like Starcraft) or just recording a sequence of a game for review later.
old question but, you can have a version number on save files so when you change something in save, you change version number and keep old version readers all the time if u want to have backward compatibility.
good but can i use binary format file ,to be stored in database like Mysql or Mongodb , so the player can keep his game persistent despite changing the devices , which file format and database do you recommend
I feel like these serialization surrogates are harder then it should be. Looking at it, it makes sense, but you can just as well store a Vector3 as 3 separate floats without this surrogate method, imo that's faster and easier to read.
It does feel like he could add 1 minute to the video and have everything explained in full... This tutorial is written for a very small margin of people, it's kinda mind boggling lol. I understand a good chunk of it, but there's so much just randomly left out, for unexplained reasons.
For example, right off the bat, in the first 3 minutes he adds some name spaces, doesn't mention it at all, for a noob it's kinda difficult to follow along.
Does this system work in mobile games for Android or iOS?
Hi! great tutorial.
I have two questions:
- Why SaveData from 5:37 is diferent from 3:19, regarding lines 6 and 7 (the _current and current thing)? I'm assuming the singleton does not work or is related with my next question...
and
- How did you solved the error "Object reference not set to an instance of an object" when trying to access current.profile...?
Thank you.
Sorry. I didn't tell you how I got the error:
The error hapens running the "Work" from 4:41 , line 44.
I can change the toy count, save it and load, retriving the correct values but the variables inside the other class (PlayerProfile) I can not.
4:04
line 21 goes:
public PlayerProf profile = new PlayerProf();
You have any update on this?
@@CyberStudios Yep!... If I remember correctly, but... don't remember how. Anyway, after one week of crying and banging my head against the wall I was able to figure out a solution... Here you have the scripts I use... try to make sense of them because I really don't remember how...
drive.google.com/file/d/17EovyHDCkgzvTsIy68GXtcSHT8fbzz1B/view?usp=sharing
@@HomeGameCoder omg you are a life saver!! Thank you, gosh these tutorials are more confusing than the WOW situation. My biggest grattitude!!!!
Great tutorial! could you please upload the project or post the link if it's already uploaded ?
very nice - does something like this exist for multiplayer games as well?
When SaveData.current can't be assigned a value because it's read only just add the following below the body of the get statement in the SaveData class's singleton: set { _current = value; }
It worked for me... I think😊
Hey, would you mind helping? I am getting a non instance of object, when using the current.profile.characterName. I am not sure how this is null? How does one set data then?
@@CyberStudios if characterName is a string, try setting it equal to "" in the player data class.
is the data saved automatically on google/ google play services as well or we have to do something extra for it as well?
I want to use this system to store the data on the amazon s3 bucket , for all my players game state , but the really problem that is bothering me , what if I want to add new features to my game , how shall the file schema change can be implemented upon the existing binary files , plz reply
you are going the change the class implementation, if the binarydata does not have this property to set, it will set as default value, so in that case you need to set your default value or keep it as default of the value/reference type. so keep implementing :)
I have a very specific question, would this system support serializing scriptable objects or do I need to create a surrogate for those as well?
This seemed like a great tutorial before I actually tried to implement it. Watched through the video once, yeah I understood everything, so decided to follow along. Nope... it turns out there are critical pieces missing from this tutorial right before you build the UI. I followed up to this point, and don't understand how the saving is working when you press the save button. Can't progress any further due to errors with the load path and SaveData instancing. Looks like wasted time, unfortunately. I recommend on this one you go back through your video following along to see where you have missed these key components. I've followed a few of your other videos very easily to completion, so it looks like you just missed a key explanation here.
Same boat... I am now trying to figure out how to write the actual save function...
if it's any use I quickly made a bare-bones example of how to use it, but instead of cars and dolls I've used coins and notes. I hope this helps you understand how it works
public void SaveProgress()
{
SaveData.current.coins = coins;
SaveData.current.notes = notes;
SerializationManager.Save("example", SaveData.current);
}
public void LoadProgress()
{
SaveData.current = (SaveData)SerializationManager.Load(Application.persistentDataPath + "/saves/example.save");
coins = SaveData.current.coins;
notes = SaveData.current.notes;
}
I belive he rasies a GameEvent OnLoad and Onsave, that all objects that can be saved/loaded can subscribe to. See his previous making custom event videos on how it works and how to raise one
@@81gamer81 how the hell does he instances 'PlayerProfile'? everytime i try to access profile from SaveData.current.profile it gives me that the thing doesn't exist! instantiating it also doesn't work, whatahell did he do??? i hate this so much!
Thanks a lot, you helped me ❤❤❤
How well does the binary formatter handle versioning and cross platform compatibility? Would extra fields in my SaveData class break old saves?
It should work across all platforms. It should also behave as expected for newer versions of your savedata class - it will still deserialase the existing (older) properties into a newer version of the savedata class, but new properties would need to be handled/initialised when loading.
I would love a "for dummies" version of this, and i know this is pretty straightforward but i really suck at programming for now.
Amazing tutorial, thank you!
Hi so i know that this is older but would you make now multiple methods in your Serialization Manager for different scripts that your trying to serialize like I have a player and weapons. So i have made SavePlayer and SaveWeapons, Along with the load methods... Does this make sense? Thanks!
He mentions everything you need to know in order to do that. You want to save weapons? give them all ID numbers and save those. the player? save it's stats and position as ints and vector3's into the SaveData file.
What if you wanted to save a list of items and save it outside of the persistent data path? Say you wanted to set up a store and you saved all your items in a list, then the store would load the binary file when you entered?
It tells me that The name 'loadArea' does not exist in the current context. But I can't seem to see any reference to a "loadArea" in the SaveManager script in the video. Is there a reference? if so what is the reference?
The ideas here are quite useful but you should never use a binary formatter for save games as that can be used by hackers as an attack vector against your QA in the form of maliciously edited save files. More details can be found in the MSDN docs about the binary formatter describing how it cannot be made safe and why it wouldn't be used for this purpose.
Yep, at the time the video went out this wasn't a known issue, however since the MSDN Docs have been updated the pinned comment explains the update. I'll eventually walk through an alternative in another video, but the underlying concepts for the system are still the same -- you'll just need to use one of the different serialisation methods.
@@GameDevGuide Well i was blind for certain hah, completely glossed over that. You have it covered there certainly (though i would if you can bother add a video sticker at start etc)
"If you found anything useful in the video"
Me: All of it!!.
Playerprefs starts to become a real mess, real fast. It's like that draw or cupboard you have in your house, you know, the one full of junk that you don't even want to spend more than 20 seconds looking in LOL.
Thank you very match!!! Very useful! Great work!!!!
If it were possible I'd subscribe twice.
Great video! Question: suppose you were making something a bit more complex where you wanted more types of objects with their own savable data (say a RTS game or RPG). Which approach would you go with for the ToyData class?
1-Make one universal ToyData class that holds all the data you might ever want to save
2-Make subclasses of ToyData with their own additional data, possibly making use of interfaces for accessing data
3-Make ToyData into an Entity style class that is mostly empty but can hold components that are accessed with generic GetComponent function
All of these have pros and cons...1 is potentially clunky if you need to add more data, but is also the simplest and fastest. 2 runs into the issue of inheritance vs composition. 3 has composition, but that also means accessing the components may have a performance cost, plus you now need to worry about the actual composition (might need to make factory classes for example).
Question, how do I get the load buttons to display the save data information rather than just the name?
thx im making a game with a complex level building system so i need to save a lot of data :)
what is that GameEvents.current.onLoadEvent?
Hi please tell me how to save material changes at runtime???
If I make an inventory system in the game will it save the things in the inventory?
Nice! Thank you 👍