How To Create An Advanced Save System In Unity

แชร์
ฝัง
  • เผยแพร่เมื่อ 9 พ.ย. 2024

ความคิดเห็น • 111

  • @JasonStorey
    @JasonStorey 4 ปีที่แล้ว +50

    great video as always.
    One small extension you can add to avoid possible data corruption on crashes: before you write the save file, check if it exists, copy it, change extension to .bak, save the new data and delete the .bak. in this way if your game or computer crashes mid game/save on load you can check for a .bak file, check if the date is newer, if so, rename current sav to .temp, restore the .bak and recover the data, delete the temp file. There are some other fun tricks you can do like a sha1 hash to tell if a save file has been user tampered with outside of the game too, but that is imo far less important that ensure save files dont corrupt.

    • @zapposh
      @zapposh 4 ปีที่แล้ว +1

      Would you mind explaining the gist of your sha1 hash trick for detecting if the file has been hampered with? Much appreciated. Thanks.

    • @chris.davidoff
      @chris.davidoff 3 ปีที่แล้ว

      This is a beautiful gem to find in the comments! Thank you!

    • @captainufo4587
      @captainufo4587 3 ปีที่แล้ว +1

      I have recently read a series of worrying articles about the vulnerabilities in the binaryformatter deserialization. How does the industry react to that? What's the preferred alternative (if any)?

    • @chris.davidoff
      @chris.davidoff 3 ปีที่แล้ว +1

      @@captainufo4587 I mean what reason is there to care? Binary has always been "hackable", it's just a matter of looking for the patterns. But truthfully, why put in the time to prevent this, it's the player's choice to modify their files

    • @captainufo4587
      @captainufo4587 3 ปีที่แล้ว

      @@chris.davidoff I wasn't referring to that. Personally I think that if someone wants to cheat in their single player, they are free to do it. I was mentioning articles like this: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide#preferred-alternatives

  • @kimjongduck5335
    @kimjongduck5335 4 ปีที่แล้ว +33

    Dude you've been on point about the subjects I wanted to see tutorials in : Photon networking, ML Agents, save systems... Awesome job, man, your channel is a gold mine

    • @DapperDinoCodingTutorials
      @DapperDinoCodingTutorials  4 ปีที่แล้ว +3

      Glad I've been able to help so much recently! Hope you continue to enjoy the content :)

    • @aymonshik
      @aymonshik 4 ปีที่แล้ว

      @@DapperDinoCodingTutorials great work, please make a tutorial about auto saving and loading using photon multiplayer, when ever the player logs in, his saved state loads up from the server .

    • @artfool2007
      @artfool2007 ปีที่แล้ว

      @@DapperDinoCodingTutorials how would i go about saving a keycode with this ?

  • @kayturs
    @kayturs 4 ปีที่แล้ว +3

    I learn more listening to you speak for 15 minutes than listening to an hour of most tutorials. Thanks for the great content!

  • @SebastiranLoL
    @SebastiranLoL 4 ปีที่แล้ว +10

    This is really great. I keep on refactoring my code every time I watch your videos. These are the kind of tutorials that help me finish my projects instead of having this constant demotivating feeling that something in the code is going to cause problems later on.

  • @stillzen-dev
    @stillzen-dev 5 หลายเดือนก่อน

    yeah dude, the scalability factor is a must and i’m relieved that a 16 minute video can provide me with that.
    got yourself a new sub!!!

  • @Obelardos2
    @Obelardos2 4 ปีที่แล้ว +12

    Thanks! What about spawned objects on runtime? How to restore a spawned aobjects? And how to store referenced values?

    • @craftlofer9974
      @craftlofer9974 3 ปีที่แล้ว +1

      i didn't watch the video yet but maybe make it so they save their position/stat on update and store it to the save? cloned stuff would have the scripts you give them

    • @oculusquest6703
      @oculusquest6703 2 ปีที่แล้ว +1

      @@craftlofer9974 Not on update thats to inefficient maybe every few seconds

    • @craftlofer9974
      @craftlofer9974 2 ปีที่แล้ว +3

      @@oculusquest6703 i posted this when i didn't know how much on update lags when used incorrectly, better solution would be to save their position when you exit/pause/autosave the game and load them when you enter the game

  • @kaanapan1183
    @kaanapan1183 3 ปีที่แล้ว

    After I watched several videos, this one by far was the best saving system. Even though this is a little bit more complicated than others, this one probably will do my job with a little modification in the design if needed.

  • @JasonWelch
    @JasonWelch ปีที่แล้ว

    Good video. I often like to see what other developers do as a bit of a sanity check for myself. I have a game save manager within my persistence scene and as game objects spawn / get destroyed, they register and unregister themselves from various managers, including the game save manager. I did however over complicate my game save system by using generics, but I may change it now to use a simple object like you have. It'd definitely help reduce some coupling issues.

  • @vellyxenya3970
    @vellyxenya3970 3 ปีที่แล้ว +1

    I was looking for a solution and considering different alternatives. This convinced me right away, it's clean, simple and scalable. Implemented it right away :) Thank you!

  • @BriShep123
    @BriShep123 2 ปีที่แล้ว +4

    From the Microsoft documentation: "Warning
    BinaryFormatter is insecure and can't be made secure. For more information, see the BinaryFormatter security guide."

  • @BeanBanditSV
    @BeanBanditSV 3 ปีที่แล้ว

    I could have saved myself a lot of time and frustration if I'd seen this a week ago. Still, better late than never! Thank you, this was by far the best tutorial for this I've seen on youtube.

  • @donmacsween2842
    @donmacsween2842 4 ปีที่แล้ว +4

    Great video (as always) but is there an alternative to using Guid for objects I want to save but created at runtime?
    Also, following on from your other great videos on DOTs wouldnt this be a good candidate for conversion, as it is performing many similar actions across multiple objects?

  • @PHxii
    @PHxii 4 ปีที่แล้ว +4

    Hello, I was following your item system and rpg system tutorial series and was wondering if I need to implement your saving system for saving the inventory, if so how would you recommend going about it? It keeps spouting out null references exptions when I put savable entity on the inventory slots which doesn't happen with other things, thanks.

  • @chris.davidoff
    @chris.davidoff 3 ปีที่แล้ว

    This is amazing, I've been thinking of how I might come up with a solution like this and.. here you've already shown the world how to do it :P

  • @fulongfromthegrave
    @fulongfromthegrave 4 ปีที่แล้ว +2

    This is pretty awesome content and the kind of topics we need! Keep em coming please 🙏🙏🙏

  • @Rambow145
    @Rambow145 4 ปีที่แล้ว +3

    This is all good like all the others but. so many miss that this will not work for items that are not in the game and has to be spawn. No how to that shows how to spawn the items back and set them to the transform. and the only one showing how to do this is missing half the stuff in the video.

  • @clippy911
    @clippy911 12 วันที่ผ่านมา

    Great stuff!
    Thanks for sharing.

  • @zapposh
    @zapposh 4 ปีที่แล้ว

    Excellent video, thank you. Is there a simple way to make the saved data even less human readable, without some obfuscation plugin? Perhaps via the formatter?

  • @GroberR
    @GroberR 2 ปีที่แล้ว +1

    Could you make version of this with Json?

  • @Revard0001
    @Revard0001 3 ปีที่แล้ว +6

    Nobody is going to point out that he never mentions how to make the Guid??? I couldn't proceed further in the tutorial because of that...
    For those that wondered like myself, its actually by : using System;

    • @PoloMarco1337
      @PoloMarco1337 3 ปีที่แล้ว

      Thank you my dude

    • @Haavenstadt
      @Haavenstadt 2 ปีที่แล้ว

      Thanks! For those interested: can be seen at 1:24 of the video

  • @SebastiranLoL
    @SebastiranLoL 4 ปีที่แล้ว

    Question: I see you are using FindObjectsOfType to restore all states, and that works great if the scene already contains the objects for which you want to restore the data. But what would you do if you also had to initialize the objects themselves? For example, in a tower defence game where you want to load up the game with a save file that instantiates the previously placed towers, and then restores the state. How would you manage the instantiation process?
    I'm currently using a save file to save the tower-type-id and position of the tower. Then go through a list (saved in a scriptable object) that contains all the different tower prefabs and allows you to compare the id's to find the correct one.

    • @rohitaug
      @rohitaug 4 ปีที่แล้ว +1

      My first guess would be to use a factory class with a SaveableEntity component which handles spawning objects. This would keep a reference to all objects of that specific type created and would pull relevant data from them in its CaptureState() method. Then in RestoreState() method it could re-instantiate the objects initialized with the data pulled from the state object. I may be oversimplifying it though, I haven't given it enough thought.

  • @ShaharHarshuv
    @ShaharHarshuv 4 ปีที่แล้ว +2

    I think ISavable should have a generic type so you won't have to write object.

  • @reendevelops
    @reendevelops 3 ปีที่แล้ว

    Very nice codes. Exactly what I needed, although I still need a bit of help.
    How do we save sprites?
    How do we destroy, let's say, a newly spawned object if they were after the save?
    Thanks!

  • @soverain
    @soverain 4 ปีที่แล้ว +1

    Hey man, great stuff! I wonder how this save system could work with ScriptableObjects. The standard with SO seems to be to serialize the entire object and then override it completely when loading. I used such solutions in SO heavy projects but sometimes you can't just use SO everywhere and you want to save some MonoBehaviours too. The goal is to have a all-in-one solution if possible because using and maintaining 2 save systems is really not ideal. Do you think your save system could work with SO?

    • @mundovtor
      @mundovtor 2 ปีที่แล้ว

      Im using scriptable object instances for storing items on chests, wondering how to implement this save system to account for this. I am so lost

  • @voidstarstudio8070
    @voidstarstudio8070 3 หลายเดือนก่อน

    Is it posible to make an addition to this to save object that are created during play time by the player

  • @Linetaru
    @Linetaru 4 ปีที่แล้ว +1

    Thanks for this, useful tutorial.
    I have questions, Save file can be modified, if you load it then you can modify saving data by saving file ?
    Is there a way to encrypt the save file ?

    • @DapperDinoCodingTutorials
      @DapperDinoCodingTutorials  4 ปีที่แล้ว

      I'm a bit confused at what you're asking with your first question and the answer to your second question is yes. There are plenty of encryption methods online and all you have to do is encrypt the data before it is saved to a file and then decrypt as soon as you load from the file.

    • @Linetaru
      @Linetaru 4 ปีที่แล้ว

      ​@@DapperDinoCodingTutorials My first question was if we save a file from our game and we go to the file it is possible to change the content and modify what it will be loaded.
      I'll try to encrypt save file to avoid modification.

  • @GameBob
    @GameBob ปีที่แล้ว

    Every time I follow a tutorial on saving, even if I copy everything 1 to 1 I can't get it to work. it throws up errors everywhere. I double, triple check every singe word on the page and nothing is different from what was on screen. I was planning on copying it all to then make the changes I needed as time went on while I adjust for what will fit better for my game. I can't do that if I can't even get the original script to work. Currently the only thing left for me to fix is the SaveableEntity script. it's throwing up errors about Guid, File, FileMode, BinaryFormatter not existing in the current context... but the worst thing of all that is the bane of my existance right now. It says that Dictionary has no definition for a comma. A COMMA. it's the one between the ()

  • @ZoidbergForPresident
    @ZoidbergForPresident 3 ปีที่แล้ว

    3:23 Wouldn't this be the ocasion to use ISaveable here?

    • @kaanapan1183
      @kaanapan1183 3 ปีที่แล้ว

      why? What are you going to do with T in the interface?

  • @gmangman123
    @gmangman123 ปีที่แล้ว

    Thank you Master!

  • @ShaharHarshuv
    @ShaharHarshuv 4 ปีที่แล้ว

    Amazing design! I love this solution. Thanks for the advice.

  • @jenniferroth7824
    @jenniferroth7824 3 ปีที่แล้ว

    This is great! Always good stuff on your channel. Although for any other brainless ones out there like me make sure you lower case the object reference on the interface🤦‍♀️

  • @rohitaug
    @rohitaug 4 ปีที่แล้ว

    So if I understand right, this wouldn't save the state of other inactive scenes? I know you said it loads a save file and overwrites only what is necessary but what happens if the player plays through a scene without saving in it? There would need to be some autosave functionality but having the ability to save be dependent on the existence of a previous save seems a bit finicky.
    |
    What if instead the scene, right before it unloads, stores its own state in a singleton game object which also implements ISaveable, has a SaveableEntity component, and uses DontDestroyOnLoad function to have it persist between scenes. This game object would just contain a dictionary of states for all scenes. Then when it's time to save, the current scene would save its own updated state into this game object which is then serialized into a file.
    |
    Would that be better or have I gravely misunderstood something here?
    |
    EDIT: Of course, the singleton object would also store what was the last active scene so only that scene is restored on load.
    |
    (TH-cam is not letting me add newlines unless I do this terribleness)

  • @oh-facts
    @oh-facts 2 ปีที่แล้ว

    Question: If I have a prefab, should I generate its id, and then copy paste it in every scene it comes in?
    I tried generating the id in the prefab menu, but it doesn't reflect in scenes

  • @MrSmoofist
    @MrSmoofist 3 ปีที่แล้ว

    First thing First, Amazing work mate really good tutorial this is some next-level stuff!!
    Second, a question: let's say I want to update the "levelSystem" file data from other scripts, is there a good way to do it? (Considering that the values are private and if I use any type of update it forces it to go one way)

    • @MrSmoofist
      @MrSmoofist 3 ปีที่แล้ว

      Don't mind me rushing to the comment section, I found the solution by making a property for each field. So just thank you now :D

  • @Havie
    @Havie 8 หลายเดือนก่อน

    Not sure exactly how this scales into truly complex save-systems , think Total War style game where you have a bunch of factions, characters, armies and things all running around, a bunch of runtime data and 'non mono' classes being instantiated at runtime and held in potentially circular references. 🤔

  • @tqacks1769
    @tqacks1769 3 ปีที่แล้ว

    im a begginer, is the namespace thing at the top needed? or is it just there? because i think the script is only in the public class's brackets but im not sure

    • @gtastic5375
      @gtastic5375 3 ปีที่แล้ว

      If systems are in different namespaces, other systems can have scripts/classes with the same names and it won't matter. This becomes more of a thing as you add new features and systems to your project.

  • @adamlutz885
    @adamlutz885 4 ปีที่แล้ว

    Does this function with Mirror Networking as well?

  • @NotsoEP
    @NotsoEP 3 ปีที่แล้ว

    So...what if an object is destroyed and you save? how would you go about removing that on save so on load the object is not still there...

  • @jreffjeff7909
    @jreffjeff7909 ปีที่แล้ว

    Would this work for mobile games?

  • @JohnVanderbeck
    @JohnVanderbeck 2 ปีที่แล้ว

    A GameObject internally already has a GUID. Any specific reason for not just using that instead of generating a new one?

    • @maximdaigle
      @maximdaigle 4 วันที่ผ่านมา

      Because that GUID can change at any time.

  • @MedicMainDave
    @MedicMainDave ปีที่แล้ว

    you might also want to check if(!(_saveable.GetType().ToString() == "SaveableEntity")) or whatever the Saveable Entity script is called for you, otherwise you'll get recursions and get a massive amount of data leaks! Hope this helps if you get this issue :)

  • @hesamgol3792
    @hesamgol3792 2 ปีที่แล้ว

    how we can deserialize the txt file and save it to check out inside the file and manage it?

  • @81gamer81
    @81gamer81 4 ปีที่แล้ว

    Bunny83 made a UUID script that guarantees uniqueness. If one is very concerned about the seemingly extremely low risk of dupes. Dupes would be a pain to debug/detect I think if someone reports it

  • @goonario
    @goonario 4 ปีที่แล้ว +2

    Wow thank you for this

  • @SaimoreFilms
    @SaimoreFilms 4 ปีที่แล้ว

    So will this save the position of my character? I for some reason didn’t understand

    • @ljhoser5842
      @ljhoser5842 4 ปีที่แล้ว +1

      no you must implement that yourself

  • @_ciraz_
    @_ciraz_ 3 ปีที่แล้ว

    Hey, I have a question. How to make the saving work automatically?
    For example, I join the game and I want the data to automatically load, without the player needing to press anything. And when the player leaves the game, his data should be automatically saved. I heard from a tutorial that I would have to do it with "OnEnable()" and "OnDisable" but I am not sure.
    I hope that someone can help me with this.

  • @FabioBeifuss
    @FabioBeifuss 3 ปีที่แล้ว +1

    Hey, I'm having an issue while deserializing, on the "private Dictionary LoadFile()" function
    I have the exact same lines of code but I'm getting an error: SerializationException: End of Stream encountered before parsing was completed.
    Searched online for a solution but didn't find it :(
    I thought I was using the wrong namespace, but doesn't seem to be the case, anyone can help me pleeeease!!!
    (Unity 2019.4.11f1)

    • @GroberR
      @GroberR 2 ปีที่แล้ว

      I have same issue did you find solution?

  • @voidstarstudio8070
    @voidstarstudio8070 ปีที่แล้ว

    It keeps giveing me "Guid dose not exsist in this curent context"

  • @Birch55
    @Birch55 4 ปีที่แล้ว

    if (stateDictionary.TryGetValue(typeName, out object value))
    line 36
    Assets/Scripts/SaveableEntity.cs(34,51): error CS1644: Feature `declaration expression' cannot be used because it is not part of the C# 6.0 language specification
    plz help
    im using unity version 2017.4.40f1

    • @Revard0001
      @Revard0001 3 ปีที่แล้ว

      Can't do much, I use the 2018 and was able to access a feature that allows me to use a newer version of unity, but I'm pretty sure its what that causes me some issues right now...

  • @tahjhightower125
    @tahjhightower125 ปีที่แล้ว

    I get the error " The type or namespace name 'Serializable' could not be found (are you missing a using directive or an assembly reference?" on the Level System tab. Can anybody give assistance.

    • @MedicMainDave
      @MedicMainDave ปีที่แล้ว

      I am guessing you forgot to put the [] brackets around the Serializable tag?

    • @GameBob
      @GameBob ปีที่แล้ว

      @@MedicMainDave nope same thing happened to me.. brackets are there
      I added the using statement using system; and it worked but I don't understand why it didn't have that problem in the video. I've literally copied 1 to 1 but things are not working at all. nothing but errors coming up from saveable entity

  • @tylerpinney3077
    @tylerpinney3077 2 ปีที่แล้ว

    This Doesnt work, typed it line for line, triple and quadruple checked it. however it is throwing errors left and right

  • @micheleguardabasso8162
    @micheleguardabasso8162 2 ปีที่แล้ว

    can you please help me for save system in my project?

  • @rizkimaulanakusuma2497
    @rizkimaulanakusuma2497 3 ปีที่แล้ว

    inventory save load system

  • @dirt410
    @dirt410 3 ปีที่แล้ว

    EDIT: Nevermind! I accidentally put SaveableEntity on the same gameobject as another ISaveable script. OOPS!
    I'm getting a "SerializationException: End of Stream encountered before parsing was completed" error. The console is pointing me towards LoadFile(). Specifically the line returning the deserialized filestream. Am I missing something obvious or is the binary formatter just not working in this instance? i'm using Unity 2019.4.21.

    • @Megajmaster1000
      @Megajmaster1000 2 ปีที่แล้ว

      Hello, I'm currently running into the same issue but I don't fully get how you dealt with the problem. Could you elaborate please?

  • @bhautikranpara3680
    @bhautikranpara3680 4 ปีที่แล้ว

    hello sir,
    how to use anti memory hacking or
    how to make code like no one can hack ?
    can u make a tutorials on it ?

  • @ericbeaulieu419
    @ericbeaulieu419 3 ปีที่แล้ว

    Something small I made on the script, will auto-generate it once a prefab is brought into the scene. If there is someone who can expand upon this by all means, please. I followed this to make overworld items save once picked up in my game and it works perfectly. Thank you for your help!
    public class SaveableEntity : MonoBehaviour
    {
    void OnValidate()
    {
    if (gameObject.scene.name != null || gameObject.scene.rootCount != 0 && string.IsNullOrEmpty(id)) GenerateID();
    }

  • @jackgimre431
    @jackgimre431 4 ปีที่แล้ว +3

    hello!

  • @Paanch_Tanmatra_Studio
    @Paanch_Tanmatra_Studio 3 ปีที่แล้ว

    Amazing tutorial.
    I also have a save system playlist series.
    It covers from player-pref to Firebase.
    I am currently editing the video with NodeJS as the back-end server for saving data.
    Any feedback on it will be really helpful.

  • @MelinaHristova
    @MelinaHristova 4 ปีที่แล้ว

    Hello The Harrowing

  • @stefan429
    @stefan429 3 ปีที่แล้ว

    SerializationException: Type 'UnityEngine.ScriptableObject' in Assembly 'UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
    lmao what an error

    • @sig1924
      @sig1924 3 ปีที่แล้ว

      I had the same problem, it occurred because I'd marked the SaveData as [SerializeField] and not [Serializable]

    • @beautaeful
      @beautaeful 3 ปีที่แล้ว

      Can't serialize scriptableobjects, have to make another class or whatever and save the stats there and then serialize that.

  • @nark4837
    @nark4837 4 ปีที่แล้ว +1

    *cough* driver creation in C++ next?
    definitely want to destroy vanguard out here, it is already destroying my PC enough.

    • @DapperDinoCodingTutorials
      @DapperDinoCodingTutorials  4 ปีที่แล้ว +1

      I'm currently a C++ noob, rarely use it right now :p

    • @nark4837
      @nark4837 4 ปีที่แล้ว

      Dapper Dino ahah, rip bro
      it was a joke anyway, but you probably don’t get it.

    • @equation1321
      @equation1321 4 ปีที่แล้ว

      NarkYT advanced joke

  • @andreeacreita3029
    @andreeacreita3029 ปีที่แล้ว

    for the sake of my mental state, please tell me how to link the save and load functions to actual buttons on the canvas Pleaseeeee!!!!!!

  • @jiaweiguo3987
    @jiaweiguo3987 2 ปีที่แล้ว

    Mal video