Тёмный
No video :(

Data Persistence - Save & load your game state while avoiding common mistakes | Unity Tutorial 

LlamAcademy
Подписаться 23 тыс.
Просмотров 52 тыс.
50% 1

Опубликовано:

 

25 авг 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 169   
@bassfight2936
@bassfight2936 Год назад
Thank you! It's SO hard to find tutorials that don't just say "use playerprefs lol" or indeed just refer to the binaryformatter.
@LlamAcademy
@LlamAcademy Год назад
Glad I could help!
@mattomwit
@mattomwit 3 месяца назад
Hi. I wanted to thank you for this tutorial it really helped me out. I was retying your solution to test it out and noticed you are rethrowing the exception using "throw e" at 13:10. For anyone reading this comment please use just the "throw" keyword. If you use "throw e" you will remove part of the call stack. Sorry for pointing stuff like that out. This video is one of the best I've seen showing how to do things properly and I firugred my comment might save someone some pain in the future.
@LlamAcademy
@LlamAcademy 3 месяца назад
Great feedback, Thank you! I didn't know that killed your call stack.
@zivv1147
@zivv1147 4 месяца назад
Absolutely fantastic video! RU-vid is full of tutorials for basic implementations, and you presenting the more complex and advanced topics, and doing a deep dive into them, is super useful and refreshing (and also important - this seems to be must-have knowledge to get a job in the industry as a developer). The presentation was fantastic, good explanations, and the pace is great.
@lucasdahl1118
@lucasdahl1118 Год назад
Thank you so much! I built a massive rpg world and have the story 90% done and this was up on my list, so thank you!
@poobagification
@poobagification 2 года назад
Excellent topic. I've been playing with saving and loading in my project and it's a mess. I read not to use binary formatter but there weren't any replacements suggested. it's nice to see how it can be done safe and clean.
@harshjadon1662
@harshjadon1662 Год назад
Finally someone made video on this thnx. hi, Kindly make more videos of unity challenges n other projects/tutorials for beginners Thanks
@Francisco-Gutierrez
@Francisco-Gutierrez Год назад
Thank you, I always come back to this video to remember how to save data is done!
@benrobinson1454
@benrobinson1454 11 месяцев назад
Brilliant video that helped me set up a save system that has felt so daunting a task I've put it off for a long time (as a hobby coder).. Thank you!
@sqwert654
@sqwert654 Год назад
Thank you !! Working perfectly with my game, so much easier than my playerPref method , no conversion needed can remove so much code from older method :)
@glock6554
@glock6554 Год назад
best teacher ever
@alon_vita
@alon_vita Год назад
Awesome Tutorial! thank you!
@umairjamshaid2173
@umairjamshaid2173 9 месяцев назад
Super helpfully and beautifully explained!
@Tokaku-ft2rd
@Tokaku-ft2rd 4 месяца назад
Awesome tutorial! Thanks
@LlamAcademy
@LlamAcademy 4 месяца назад
You're welcome🧡
@ericelnomada
@ericelnomada Год назад
Thank you bro! amazing tutorial!!
@sharat.achary
@sharat.achary 2 года назад
Thank you, you explain it very well. 🤝
@martin.m.kloeckener
@martin.m.kloeckener Год назад
Good tutorial, thanks! However, I would make a backup of the previous save file and delete it only at the end when the new save file has been successfully created. That way, you can be sure that you won't lose the entire save file if the game or the PC crashes / an error occurs during the save.
@LlamAcademy
@LlamAcademy Год назад
That is a good suggestion, thanks!
@ibeatboxer_9673
@ibeatboxer_9673 8 месяцев назад
What do you mean by that? In order to save a new file you should delete the previous isn't it right? Even if you create the new one how would you not have any conflict with the previous one?
@martin.m.kloeckener
@martin.m.kloeckener 8 месяцев назад
@@ibeatboxer_9673 If you delete the previous file, then save the new one you are risking to lose the player's progress. If the game crashes during the file writing or the file writing fails, the previous file is still deleted, but you don't have a new file. So no save file at all anymore. I suggested to make a copy of the previous file, then write the new file and only if this was successful, delete the copied file. This surely is a very unlikely scenario but only one player losing progress is one player too much.
@Nomad1108
@Nomad1108 3 месяца назад
​@@ibeatboxer_9673 Maybe change the file extension to .bck before creating a new .json, then delete .bck if the save was successful otherwise revert .bck to .json.
@neil_from_future
@neil_from_future 2 месяца назад
​@@ibeatboxer_9673 I mean they have extra work under it where they would just: if exist > load it > create a new file with .bak > then do the work on real one > if something wrong happened with the original > load the .bak instead.
@cheezcola
@cheezcola 7 месяцев назад
good tutorial. Thanks!
@soolydooly1234
@soolydooly1234 8 месяцев назад
thanks for making this. Although I'm going to use BinaryWriter
@Coolae450
@Coolae450 4 месяца назад
I'm getting a NullRefrenceException whenever I try to call the Load method :/
@superdahoho
@superdahoho 6 месяцев назад
so how do you save complex data? I have a class(inventory item) with image, transform, an enum, a scriptable object and another gameobject as variable. i want to save it and unity is having a hard time converting that into data. do I have to manually break down the data into primitive variables and save them?
@LlamAcademy
@LlamAcademy 6 месяцев назад
If you need to retain object references using JsonUtility is a little easier (you can still do it with Json.NET, but it’s a little extra work). For this type of thing I would have an item scriptable object that had references to the image and prefab and whatever other project files it needs. Whenever I need to instantiate the UI I would read the prefab from the SO and instantiate the prefab
@imc0der
@imc0der Год назад
Nice tutorial thanks
@skelhain
@skelhain 2 года назад
Excellent lecture! Your coding style is clean and professional and teaches good programming habits. I have a hard time tackling Game Serialization and this video gave me some good ideas. One question if I may. I'm working on a Baldur's Gate-like game, with lot's of area transitions and after many days of brainstorming I still can't decide what approch to take for bringing the player party to another area with inventory and equipped armor/weapons. I'm going back and forth between DontDestroyOnLoad and using a persistent scene with additive scenes for each area, but both ways feel wrong and hacky. I seriously would prefer to save everything in a scene, destroy it and reload everything in the next. May I ask you and others, what approach you think would be best or which approach would be horrible to take?
@LlamAcademy
@LlamAcademy 2 года назад
There's a lot of things to consider there. If you're okay having the kind of clunky "fade to black" or "loading screen" the full load of a new scene and just re-instantiating your player/group objects (including weapons/armor, etc..) at the "start point" on the next level is the simplest and most memory efficient way of handling that. For more of an open world feel, I think additively loading the scenes and keeping the players/group always active is the way to go.
@skelhain
@skelhain 2 года назад
@@LlamAcademy Thank you for sharing your view! I think method 1 it is for now. With this serialization system it shouldn't be too hard to implement. I'd really love to see more videos about this topic.
@Micahiscoo
@Micahiscoo 9 месяцев назад
@@skelhain did it work
@evanlane1690
@evanlane1690 Год назад
Would it be safer to write a second save file if you find a save file already exists? Then when the file is written successfully, you delete the old save? That way if anything goes wrong during the save it can gracefully revert to the old save?
@LlamAcademy
@LlamAcademy Год назад
Maybe? At some point you're going to want to write over the original save. I guess if the save to the temporary "new" file succeeds and the write to the "real" save file fails, you can use the temporary one. If the problem with writing persists (maybe disk space is full or something) then the next time you try to write to the temporary one, that may also fail. You could build a very robust system to manage this kind of thing, but in my opinion, the risk of this is very small. Having a cloud save or cloud backup would be the safest option to prevent total save file loss.
@MagicPigGames
@MagicPigGames 2 года назад
I've run into cases where my data structure goes > 10 layers deep, so Serialization fails. In those cases, I've found that I can store some data classes, like "Inventory" or what not, as a JSON string, and then just save the various strings. On Load, I can load all the data in two passes -- loading the saved data, then loading the saved JSON strings. I'll have to come back after the day job to learn why using JSON Utility is not good! :D
@LlamAcademy
@LlamAcademy 2 года назад
Sounds like you already found one of the issues with JSONUtility 😉. I got some feedback as well instead of using Newtonsoft (JSON.NET) you could use System.Text.Json (docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer?view=net-6.0) which is C# native JSON support that works effectively the same, but can even be faster than JSON.NET
@MagicPigGames
@MagicPigGames 2 года назад
@@LlamAcademy Oh thanks! I'll have to keep this in mind when I update my save/load system!!
@bravo7989
@bravo7989 Год назад
Great Videos! I am learning more every day. You mentioned that you shouldn't use the binary formater. Can you explain why?
@LlamAcademy
@LlamAcademy Год назад
Yes, but I think Microsoft does a better job at it than I can, you can see their guidance here: docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide
@FiceGamingTVStream
@FiceGamingTVStream 4 месяца назад
i really enjoyed your video. The only thing i have a gripe with is i still want evidence on why not using the unity JSONs for saving. You said it doesn't support complex types, but your example wasn't complex either and was just nested standard data types in the json object. If you could show in a video one day complex values being stored then maybe I would be swayed in the direction your talking about but your approach seems like there's overheard development without showing a true scenario of it working with the implementation. I still really love the video and watched it till the end
@LlamAcademy
@LlamAcademy 4 месяца назад
Well, even simple Dictionaries just don’t save with JsonUtility. I’m sure you could come up with an event/observable+visitor system that could collect all objects that have data that need to be saved and write only once to the disk without worrying about multiple things trying to write at once. That would be pretty sophisticated and cool
@FiceGamingTVStream
@FiceGamingTVStream 4 месяца назад
@@LlamAcademy thank you so much for that answer and ill definitely research that a bit more! You absolutely rock!
@Nomad1108
@Nomad1108 3 месяца назад
Great video thank you! I was wondering if using a struct instead of a class for PlayerStats would be better performance-wise (thinking about an auto save system on mobile)?
@LlamAcademy
@LlamAcademy 3 месяца назад
Generally structs put less pressure on the heap so if you’re saving a lot during gameplay that could be better. I have always used a class for whatever reason and haven’t had issues with the performance, but I also haven’t saved extensively during gameplay where performance is critical.
@Nomad1108
@Nomad1108 3 месяца назад
@@LlamAcademy Good to know, thanks!
@indigotidd6663
@indigotidd6663 Год назад
What do I do if there is an exception error? it wont write to the persistent data path and I can't figure out why
@LlamAcademy
@LlamAcademy Год назад
Not sure, what is the error?
@gavinw77
@gavinw77 4 месяца назад
Saving to registry? As I understand it, MS are moving away from the registry style of storing data. UWP and W8 introduced ApplicationData (and the AppData folder). If apps store data there instead of the registry it makes for an easier cleanup, and prevents performance decay on long-life-installs.
@LlamAcademy
@LlamAcademy 4 месяца назад
This does not save to the registry
@bassfight2936
@bassfight2936 Год назад
This saves data locally to our device. What would you recommend for managing data across devices using github? Me and my friend are both working on the same unity project, synched up via a git repository. Would it be best to simply sync the folder in appdata too?
@LlamAcademy
@LlamAcademy Год назад
Do you need to synchronize the save files between members of your project? That's a little trickier... These are saved (on Windows) in the User directory. You could potentially create a separate git repo in that folder and push changes as needed. Maybe symlinking the persistent data path folder could get you there, but honestly, I haven't tried something like this before. The lowest-tech solution would be to create a folder in your main repo with like "base save files" and manually copy them around as needed
@Veil291
@Veil291 Год назад
hey, beginner game dev here I was making an arcade game (similar to flappy bird) and I wanted to be able to save the player high score so I could show it at the end of the run (or just at the top corner or something). Anyway I was wondering if you would still recommend this method and if so how would you alter it (as I think some of it might be a bit unnecessary just to save the player's high score). Thanks for any help :)
@LlamAcademy
@LlamAcademy Год назад
You can use this method to save high scores. Honestly it may initially seem like a lot, but with the framework in place it’s quite easy to handle even multiple files. If you want to save more than just the highest score, for example the top 10 high scores, this will be very helpful. If you only ever want to store the single highest score, you can achieve that with simply using PlayerPrefs.SetInt(“HighScore”, score); PlayerPrefs.Save(); And retrieve it with PlayerPrefs.GetInt(“HighScore”); That will work and will get you up and running pretty quick. If you plan to extend your game, you might want to go ahead and do this because otherwise you’ll have to undo all the other saving stuff and reimplement something more robust like this eventually anyway. Ultimately it’s up to you and the needs of your game 🙂
@WelshGuitarDude
@WelshGuitarDude 3 месяца назад
How do you link data to a monbehavior since the reference is lost when you open unity again. Such as a graph node and the monbehavior that holds the node data
@adslpiulentoditalia2545
@adslpiulentoditalia2545 Год назад
Hey Llam great video. It would be amazing if you can show how we can save Json to Google play services cloud there's no tutorials on that. It would be amazing keep storing Json somewhere from server side which is totally free. Could you make a video on that would be really helpful. I tried in many ways to save Json to Google cloud but unsuccessful. :)
@LlamAcademy
@LlamAcademy Год назад
Hmm 🤔 I'll think about that. I didn't use Google Play services. For my game I used PlayFab which handles that. It's free up to a point, but eventually you have to pay. They don't recommend launching your game on the free tier because it doesn't have an SLA
@adslpiulentoditalia2545
@adslpiulentoditalia2545 Год назад
@@LlamAcademy i used a playfab but there's more limitations that you can expect for some reason playfab didn't mention that player even if you doesn't reach 100K it's calculating each player API call for every single 5 minutes that means that you cannot log-in after that time because of limitations and that gonna cause a lot issues. That's why I moved to google play services cloud which Is absolutely free no metter the amount of players the only things that you cannot do is see the data on the cloud which is stored into google drive account for each player. But at least you can store json or variables into cloud for absolutely free. Of course there is a limitations like you can only store 3MB of data file but I think that should be enough even for big projects since my json file is 3kb at least. But there is actually no documentation about that I see some old forums that they managed to save json to that cloud but I tried and no success maybe because I'm bad at coding :( I see many games storing data to this cloud but I have no idea how. I just managed how to save separately each variables but that's gonna be a mess since a have a lot of data
@eetu16
@eetu16 2 года назад
DateTime.Now.Ticks could be replaced with the Stopwatch class, but DateTime gets the job done as well. This is the best video on this subject that I have seen, thank you!
@LlamAcademy
@LlamAcademy 2 года назад
I appreciate that, thank you 🙌
@lokeki8894
@lokeki8894 Год назад
Hi thank you for the great video! I have a slightly related(?) question regarding game data. When it comes down to having pre-existing data(such as a spreadsheet of enemy/item data), how should I go about packing the data for a game? I have heard people recommending against /Resources and I would like to hear how you would go about handling this data.
@LlamAcademy
@LlamAcademy Год назад
Personally I would load the data from a spreadsheet into scriptable objects. I’m not a fan of using csv or excel to define these relationships. Editor fooling around scriptable objects makes it much easier to deal with. However if you and/or your team prefer to work like that, I don’t see a problem with the resources folder.
@lokeki8894
@lokeki8894 11 месяцев назад
@@LlamAcademy I see. Thank you for the quick reply and this amazing video!
@druvingame
@druvingame 9 месяцев назад
I making a simple cannon shooting game for mobile, i can't decide whether i should save data on local or cloud for my game, i want to make it run on cloud to make sure internet stays on when playing game. what should i do?
@LlamAcademy
@LlamAcademy 8 месяцев назад
I actually think if you can have your mobile game not require internet connection, you shouldn't. There are many use cases such as on a plane, train, and boat, where the device may not have internet and it would be cool to still be able to play it. I actually spent a good couple months ripping out the "always online" requirement for my game so it could be played offline in these scenarios. If you need it to be online for multiplayer and anti-cheat, sure. If it's "just because" I would advise against it.
@DanWarrioR
@DanWarrioR 6 месяцев назад
Is it possible to save GameObject properties, as an transform.position, rotation, scale etc. And for example a navmesh settings for enemy: target, path, something else. If is not possible which method i should use to do that in my project? Thanks for your help
@LlamAcademy
@LlamAcademy 6 месяцев назад
Yes, but you will need to copy those into a data structure that can be serialized first (a simple class with those properties is fine) and apply them to your target objects on load
@supersentaimexicano1967
@supersentaimexicano1967 4 месяца назад
could you make a tutorial about it? It could be really helpfull pls @@LlamAcademy
@N1ghtR1der666
@N1ghtR1der666 2 месяца назад
I don't think you should be deleting the only other save before creating a new one, that's a fast way to get a corrupted save that is unrecoverable, I would change it to have multiple saves before starting to overwrite the oldest or some similar system.
@LlamAcademy
@LlamAcademy 2 месяца назад
Yup. You can build out as much framework and multi-save as you want on top of this
@DanWarrioR
@DanWarrioR 5 месяцев назад
Hello man, can you help me with this sytem because i can't understand how is it possible. FOr example, i have simple public class with fields and a few Lists with already added variables, for example in my projects it's screenResolutions list. I have list with new(1920, 1080), new(1024, 768), new(1152, 864), ...... 14 elements. For the first game starting, i'm trying to load data from my folder and it work for the first time, but if i want to restart my game(or start it again, 2x, 3x, and more). For all next game starting times my system load this data incorect. How i already said i have list with 14 elements(example) and for the first time system load this data corect, with all this 14 elements but for the next times amount of elements increasing on (amount of elements) + (default count of elements). For example, for the 2 game run my 14 elements become 14+14 =28, for the third 28+14 = 42 and so on. What is the reason for this error and how to fix it? Huge thank for the help!
@LlamAcademy
@LlamAcademy 5 месяцев назад
Sounds like I when you start your game you’re adding to the file instead of writing a new file. You’ll have to check your code carefully to see how you initialize the data and how you read/write the data. You can easily add some breakpoints or debug.logs to see exactly what your code surrounding this system is doing and I think you’ll find it pretty quickly!
@DanWarrioR
@DanWarrioR 5 месяцев назад
@@LlamAcademy I have already fixed this problem, thankfully. The problem caused my data saving with using List collections. I don't know why, but when i am using a List collection, the files reads wrong, that's why i got (amount of elements) + (default amount of elements) every time. I don't know why, but when i change it to simple array it started working
@scdijkens
@scdijkens Год назад
Hi this looks great, I am struggling a bit with saving lists of Custom classes however. In my case I have 100's of "Character" classes each with their own "Family" class reference of the Family they belong to, but then the Family class has a list with references to all the Characters that are part of the Family. I believe this is what is causing the Serialization function to throw this error: Unable to save data due to: Self referencing loop detected. How do I still serialize those references etc.? Also for serializing unity colors do I need to turn them into rgba float arrays?
@LlamAcademy
@LlamAcademy Год назад
Usually when you have cyclical references like this, it’s an indication that the data model design is flawed. Without knowing the details of your game, it sounds to me like “Family” would be an object that HAS multiple “people” or “Characters”, not the other way around. If you do need these references, this stackoverflow may help: stackoverflow.com/questions/35869705/handling-circular-reference-with-newtonsoft-json
@scdijkens
@scdijkens Год назад
@@LlamAcademy Thanks I'll take a look. How did you format the JSON at 11:40 ? I googled and found CTRL K CTRL D but Visual Studio gives an error formatting is not currently available...
@scdijkens
@scdijkens Год назад
Nvm got it, apparently i didn't have the web component installed on VS.
@willcroft5105
@willcroft5105 3 месяца назад
Could someone please explain how to use this in a basic game not having the Demo.cs stuff? Like I have a simple player with a health int, ammo int, etc. How do I use it? Do i have to modify the existing player controller to have all new Data stuff?
@LlamAcademy
@LlamAcademy 3 месяца назад
In this demo class here is just showing us the "game data" that is in PlayerStats. I think I didn't do a good job explaining in this video that you need a Serializable data structure to store to the file. If your game has all your data stored on a monobehavior you have to do some work or refactoring to have a "clean" serializable class to save/load on the disk.
@Criss10_
@Criss10_ Год назад
Hi nice video! i have a question, where i can generate the key and the iv?
@LlamAcademy
@LlamAcademy Год назад
Hi 👋 The Aes instance that is created here: 17:21 will automatically generate an IV and Key. What I did was just copy/paste the values out from one that was generated at this time and started using those every time as those strings you see at the top of the JsonDataService class.
@jimmmybacon9043
@jimmmybacon9043 Месяц назад
Its telling me that the namespace newtonsoft could not be found despite me having just downloading it.
@TheRichardMarks
@TheRichardMarks 10 дней назад
Rebuilding the project in visual studio solved this for me.
@NaviYT
@NaviYT 9 месяцев назад
Hey there! Let me start out by saying AMAZING TUTORIAL! I love the way this system works and how clean and reusable the code is. I do have an issue though. While the file is being written to correctly, the data is not being retrieved correctly. For example. Let's say I have an array of weapon classes that I'm saving. The file gets written to as show below: { "Setup": { "ID": "WeaponClassSlot.1", "DisplayName": "a;sdkfja;sdlkfja;sdjf", "PrimaryWeapon": { "ID": "TestID", "DisplayName": "TestDisplayName", "WeaponRef": null, "WeaponSkins": [], "WeaponAttachments": [] }, "SecondaryWeapon": { "ID": "", "DisplayName": "", "WeaponRef": null, "WeaponSkins": [], "WeaponAttachments": [] }, "Knife": {}, "Utility1": null, "Utility2": null, "Utility3": null }, "name": "WeaponClass_Slot1", "hideFlags": 0 }, { "Setup": { "ID": "WeaponClassSlot.2", "DisplayName": "Weapon Class 2", "PrimaryWeapon": { "ID": "", "DisplayName": "", "WeaponRef": null, "WeaponSkins": [], "WeaponAttachments": [] }, "SecondaryWeapon": { "ID": "", "DisplayName": "", "WeaponRef": null, "WeaponSkins": [], "WeaponAttachments": [] }, "Knife": {}, "Utility1": null, "Utility2": null, "Utility3": null }, etc... However, when I use the load function and attempt to print the file to the console (similar to how you do with the text field) I get empty values like this: Any Idea on how I can fix this? Perhaps saving an array of a custom data set is not supported? But then that wouldn't make sense because the file gets correctly written to. It's only when trying to load the data back into an array of this data type that it returns all values as null. Thank you in advanced, and thank you for the video :) Loaded from file: [ { "Setup": { "ID": null, "DisplayName": null, "PrimaryWeapon": null, "SecondaryWeapon": null, "Knife": null, "Utility1": null, "Utility2": null, "Utility3": null }, "name": "WeaponClass_Slot1", "hideFlags": 0 }, { "Setup": { "ID": null, "DisplayName": null, "PrimaryWeapon": null, "SecondaryWeapon": null, "Knife": null, "Utility1": null, "Utility2": null, "Utility3": null }, "name": "WeaponClass_Slot2", "hideFlags": 0 }, etc...
@NaviYT
@NaviYT 9 месяцев назад
For anyone dealing with this in the future. My issues were not having public setters. I'll leave an example below. Normally for my values I incorporate private setters to prevent cheating. The way I go about this is: public bool MyBool => _myBool; [SerailizeField] private bool _myBool = false; Removing the private setter fixed the issue and now the Json deserializes correctly
@ericgardiner7715
@ericgardiner7715 5 месяцев назад
As a newcomer to coding I found this very difficult to follow because of the demo script that you don't write in this tutorial and I don't understand how to save and load the data across my other scrips in my game.
@LordZandaurgh
@LordZandaurgh 3 месяца назад
Yeah I'm having the same issue. Have you figured it out?
@ericgardiner7715
@ericgardiner7715 3 месяца назад
@@LordZandaurgh I sort of figured It out. You can't load and save the same JSON file in more than one script in your scene otherwise it overwrites in strange ways. Is there a particular part that's not working for you?
@LordZandaurgh
@LordZandaurgh 3 месяца назад
@@ericgardiner7715 Well I'm trying to use one script to store and alter the stats of my player and it would be convenient if I could call a function to save and load the data within that script. I'm also confused about the whole Demo script used in the video.
@ericgardiner7715
@ericgardiner7715 3 месяца назад
How I can explain it is you need two scripts: 1: that defines the JSON file that will be used for storing the data, 2: the script that gets the JSON file and creates an instance of it (Load the data), reads and edits that insane (Accessing and setting the data locally), and the replaces the JSON file with the edited instance (Saving the data). Note that I have not implemented Encryption even though I have created a bool for it. //this is what my first script is to define the JSON file is: using System; using System.Collections.Generic; [Serializable] public class CarData { public float SuspentionHeight; } //In my second script I declare the JsonDataService and the "local instance" of the data file that I defined in the previous script, as well as the unused encryption bool. using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CarCustomiser : MonoBehaviour { //Declare Data saving variables private IDataService DataService = new JsonDataService(); private CarData CarData = new CarData(); private bool EncryptionEnabled; void Start() { //load data in start CarData = DataService.LoadData("/Car-Data.json", EncryptionEnabled); } //this is how I read the data void ReadData() { float height = CarData.SuspentionHeight; } //this is how I set a new value on the "local instance" void SetData() { CarData.SuspentionHeight = 5; } //this is how I save the data by writing over the JSON file public void SerializeJson() { if(DataService.SaveData("/Car-Data.json", CarData, EncryptionEnabled)) { } else { Debug.LogError("Could not save file."); } } } I hope that helps, or that you managed to figure it out in the meantime.
@jacopinolaringoiatra
@jacopinolaringoiatra Год назад
"com.unity.nuget.newtonsoft-json":"3.0.2",
@scdijkens
@scdijkens Год назад
How would you go about merging different classes into the same json? like for example you used PlayerStats, how would you then add into the same file for example classes like BuildingData and EnemyStats etc etc?
@LlamAcademy
@LlamAcademy Год назад
I would use separate files. This data sounds unrelated and probably needs to be handled by different classes. If it absolutely must be in the same file, I would make a new class with properties EnemyData, BuildingData, and PlayerStats and serialize / deserialize this class. I highly discourage that route unless there is no other option.
@scdijkens
@scdijkens Год назад
@@LlamAcademy Well most games have a single save file is why. That's kind of what I am aiming for as well. Maybe some sort of way to write to the file with Header text or symbols that break up the file into different strings upon deserialization? so you'd have a string for PlayerStats which is everything under the // PlayerStats header etc? similarly for // EnemyData ?
@scdijkens
@scdijkens Год назад
I could also make a folder that contains jsons for all the data seperately for each savegame. But I feel that would look a lot less elegant inside the File Explorer... (Say a player wants to do some save-editing?)
@LlamAcademy
@LlamAcademy Год назад
Yeah. Assuming each of those is a class that holds data about each thing, then just create a class that has a property of each of those classes and serialize that one instead. Like public class SaveData { public PlayerStats PlayerStats; public EnemyStats EnemyStats; public BuildingData BuildingData; …etc } And save / load from that
@scdijkens
@scdijkens Год назад
@@LlamAcademy Makes sense! I'll try that, thanks!
@dalima7342
@dalima7342 Год назад
Greate video,but how about saving data like: public class Item:ScriptableObject { public Sprite icon; public string name; } It went wrong when i try to save Sprite and load abstract class
@LlamAcademy
@LlamAcademy Год назад
Sprite is not a serializable class. If you want to do that you may have like a sprite NAME and load that sprite after you read the file
@dalima7342
@dalima7342 Год назад
​@@LlamAcademy Got it,thanks!
@RideFixRepeat
@RideFixRepeat 6 месяцев назад
Lets say you can create multi characters or even a online co-op host/client based game, can you name the file name dynamic? Like instead of the /player-stats.json you have, could you do /.json?
@LlamAcademy
@LlamAcademy 6 месяцев назад
of course! In online games you frequently allow a player to change their name, so maybe the unique identifier for the player would be a better choice than their name though.
@karthikeyanpandiyan7333
@karthikeyanpandiyan7333 10 месяцев назад
I'm getting the wrong key or iv error. I generated one using the commented out line and copy pasted it to my const KEY and IV. It saves the file but when i try to load the content, it gives me a Null output. Help!
@LlamAcademy
@LlamAcademy 10 месяцев назад
This sounds like when saving or loading it is not receiving the Key or IV and a new instance with an automatically generated key and/or IV is being used for at least one of these operations.
@Fearofthemonster
@Fearofthemonster 9 месяцев назад
If I understand correctly, this does not save monobehaviours. I have 100 gameobjects with multiple monobehaviours, including an AI for each gameObject (which is a finite state machine containing multiple classes). I am very confused on how I should proceed with saving.
@LlamAcademy
@LlamAcademy 9 месяцев назад
I would generally advise against trying to serialize the full state of your game including all game objects, monobehaviours, etc... The save size will become unreasonably large. Instead, I would recommend to save the core pieces of data you need and when loading, respawn objects into the game and set up your monobehaviours from the save file. For example if you have some enemy AI, most likely they are from prefabs. When you save, you can save the location and core stats such as ammo, hp, energy, position, and rotation for each enemy. When you load, you spawn the prefabs and apply the data from the save file. This way you don't need to save the (same, repeated) full prefab structure for each enemy AI.
@Maxroty
@Maxroty 10 месяцев назад
Hi, I managed to successfully encrypt data and be able save it onto a file but whenever I try to load the encrypted file it gives me, "CryptographicException: Bad PKCS7 padding. Invalid length 53" which happens precisely at "string result = reader.ReadToEnd(); " I have the Key & IV auto-generated and set in variables. I don't know what I might be missing...
@LlamAcademy
@LlamAcademy 10 месяцев назад
When I had that happen it was because I just was manually tweaking a Key/IV. If I let C# generate the Key/IV, write them to the console, then copy/paste those into variables and only use those from that point on, it was always good to go. Is that the process you did for this?
@Maxroty
@Maxroty 9 месяцев назад
@@LlamAcademy Yes, that's the process I followed. I figured out what was missing, not closing the stream after encryption made decryption problematic. So all I was missing was a stream.Close(). Thanks for replying.
@Havie
@Havie 6 месяцев назад
What happens if you have many many entities with multiple sub components and they all have nuanced references to one another ?
@LlamAcademy
@LlamAcademy 6 месяцев назад
The data can be serialized like what's done here. For the references, when the objects are constructed via Prefabs or Instantiate() they should grab the references to one another. It's generally not a good idea to try to serialize all of the components of all of the objects in the entire scene.
@anellaa5070
@anellaa5070 4 месяца назад
how to change and update the data?😭😭
@LlamAcademy
@LlamAcademy 4 месяца назад
You can load the data, make whatever changes, and re-save it
@anellaa5070
@anellaa5070 4 месяца назад
i only change 1 or 2 variables at a time but when I resave it the other variables that has been changed will reset to it defaults, how to save the new data but not changing other data?@@LlamAcademy
@marekpuchon4878
@marekpuchon4878 Год назад
Are you avaliable for personal mentoring?? Your chanel is amazing!!!
@akash.anand1
@akash.anand1 Год назад
Is Cryptostream.Dispose() called automatically? If yes, does it close the Filestream stream as well?
@LlamAcademy
@LlamAcademy Год назад
Yes! Because of the syntax we are using, dispose is automatically called
@thespacecowboy420
@thespacecowboy420 5 месяцев назад
What with manifest json? what?
@Chubzdoomer
@Chubzdoomer 5 месяцев назад
The manifest file should be located at YourProjectDirectory/Packages, where 'YourProjectDirectory' is the actual name of your project's directory.
@Icy_T
@Icy_T 7 месяцев назад
Whats the benefit of using Newton instead of JsonUtility
@LlamAcademy
@LlamAcademy 7 месяцев назад
I talk about that around 3:30
@XxADONExX
@XxADONExX Год назад
does this method also work for persisting data between scenes?
@LlamAcademy
@LlamAcademy Год назад
You could use this to persist some data on one scene and load it in another, yes!
@hailelam4112
@hailelam4112 Год назад
Can you share file json?
@kiechannel8278
@kiechannel8278 10 месяцев назад
Hi I follow your video, I cannot use my own key and IV to encrypt data but I use your key it correct. Why?
@LlamAcademy
@LlamAcademy 10 месяцев назад
The most common issue I had with keys/IVs not working was an inconsistent use of them. Meaning on a write one set was used and on a read another was used. I think I mentioned in the video that to get these I made C# generate some valid key & IV then I copied those and used it. When I tried to manually make up some they didn’t work.
@kiechannel8278
@kiechannel8278 10 месяцев назад
@@LlamAcademy Thanks, I just generated my own Key and IV.
@sqwert654
@sqwert654 Год назад
Is there not a problem using "/" on a Mac for the file format? @9.48
@LlamAcademy
@LlamAcademy Год назад
Nope, this is interpreted correctly by both windows and unix-based operating systems (including Mac)
@sqwert654
@sqwert654 Год назад
@@LlamAcademy fantastic!! Was using playerprefs in my 4 player Mahjong game. This is a much better solution.
@Hoang-nn8ot
@Hoang-nn8ot 10 месяцев назад
how u can work with "using" in class my unity keep error at it
@LlamAcademy
@LlamAcademy 10 месяцев назад
I think you may need to update your scripting API Compatibility level in the Project Settings > Player > Other Settings > Configuration > API Compatibility Level and set it to .NET Standard 2.1
@Hoang-nn8ot
@Hoang-nn8ot 10 месяцев назад
@@LlamAcademy i think it my unity version problem. Can i not use "using" in "using FileStream"?
@LlamAcademy
@LlamAcademy 10 месяцев назад
@Hoang-nn8ot the “using” syntax used here is a newer c# feature. You can use the older syntax as well to get the same result learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using
@sayginisbay2365
@sayginisbay2365 Год назад
Is this same for the mobile games?
@LlamAcademy
@LlamAcademy Год назад
Yup. I use this in my mobile game!
@songerk7102
@songerk7102 Год назад
Great tutorial but you have one problem with the way you did it, it will only work with script that do not inherent from monobehaivor or any kind of inherent
@tomicz9850
@tomicz9850 2 года назад
Does this work on mobile?
@tomicz9850
@tomicz9850 2 года назад
It did work if anyone wonders. This is really high quality content!
@LlamAcademy
@LlamAcademy 2 года назад
🙂 yup. It works on all platforms that have Application.persistentDataPath defined!
@easymusictransfer423
@easymusictransfer423 Год назад
@@LlamAcademy In the Unity Documentation, it doesn't appear that Nintendo switch has a Application.persistentDataPath defined. Is this the case? I'm currently making a Level Progress Json file that gets read from and saved to (to track high scores/bonus missions completed/etc). Any help/tips appreciated!
@deli5777
@deli5777 Год назад
Awesome, I was wondering, thanks!
@yourcommander3412
@yourcommander3412 Год назад
So I was trying to format Vector3 to three floats ... ohhh ... wait I actually want to store class objects... hmmm - hmmmmm. Nah, this is better.
@awmindiegame
@awmindiegame Год назад
tutorial in which this problem was solved ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-JLGhHjlYqjU.html
@awmindiegame
@awmindiegame Год назад
there is a link to github in the tutorial description
@JustFor-dq5wc
@JustFor-dq5wc Год назад
I would change 2 things. 1) Don't save whole class, just data you need. Saving whole class can be heavy and its problematic when you change something (backwards compatibility). 2) AES is overkill to encrypt save. Key can't be securely stored anyway - you have to decrypt data client side. Simple XOR operation is much faster and do scrambling job just fine. Edit: one more thing. JsonUtility is one of the fastest parsers and create smallest amount of garbage. Source: "JSON Libraries Comparison in Unity 5.5"
@adslpiulentoditalia2545
@adslpiulentoditalia2545 Год назад
Yeah but xor doesn't read arrays and list back which AES does. I always have issues with xor. It could be in many ways unstable. For the key problem you just can encrypt byte itself to keep it safe
@thatguy9668
@thatguy9668 Год назад
While this is really well done, SERIOUSLY would be nice if you could slow down any time you are using intellisense to make connections/corrections on the errors. I have to slow the video down to 25% play speed to get a chance to see what option you clicked. Several parts where you just flew through like bat shit crazy on critical info... but then took your time talking forever on misc stuff I don't need to know day to day.
@LlamAcademy
@LlamAcademy Год назад
Thanks for the feedback. I will try to be sure to slow down or sit with the code on screen a little longer so it is easier to follow.
@thatguy9668
@thatguy9668 Год назад
@@LlamAcademy yep just a second to pause it, also thank you for replying. Additionally IdataService and JsonDataService need to be attached to something available in every scene correct? cause I am getting errors when trying to attach it as a component to my Game Manager. Saying needs to derive from monobehavior for jsondata, and then can't be abstract for idata
@LlamAcademy
@LlamAcademy Год назад
@thatguy9668 no, these are not MonoBehaviors so you don’t need to attach them to a GameObject. You can use them like any standard C# class. If you want to use them in the game manager you can just instantiate an instance and you are good to go. The full project is on GitHub, so you can check out how it was done in the Demo.cs MonoBehavior github.com/llamacademy/persistent-data/
@seksan4843
@seksan4843 Год назад
Great Tutorial, you can teach me for design plain Model with your json. i can't deserialize my plain Model ; this is my plain model public class PlayerStat { [JsonProperty("Health")] public long Health { get; set; } [JsonProperty("Name")] public string Name { get; set; } [JsonProperty("BaseAttackSpeed")] public long BaseAttackSpeed { get; set; } [JsonProperty("Level")] public long Level { get; set; } [JsonProperty("HasUnlockedSomething")] public bool HasUnlockedSomething { get; set; } [JsonProperty("HasUnlockedSomethingElse")] public bool HasUnlockedSomethingElse { get; set; } public Dictionary Equipment { get; set; } [JsonProperty("Inventory")] public Inventory[] Inventory { get; set; } } stuck it can't deserialze dictionary "JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[LabJSON.Model.Slot,LabJSON.Model.Equipment]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array."
@LlamAcademy
@LlamAcademy Год назад
From what I read here, it seems that you have stored some data in an array and are trying to deserialize it into a Dictionary. To resolve that, whenever you are saving the data of "Equipment" make sure it is stored in a key-value format.
@graig2558
@graig2558 Год назад
No back up save? Ok well hopefully literally nothing EVER corrupts when your player saves and the code deletes the only copy of the save.
@alfuplus976
@alfuplus976 10 месяцев назад
with do respect, you just waste my time, your code is not clear and ambiguous. thanks for your kind effort through.
Далее
SAVE & LOAD SYSTEM in Unity
18:20
Просмотров 1,1 млн
How to make a Save & Load System in Unity | 2022
26:56
Просмотров 188 тыс.
O'ZBEK VA TOJIKLAR ROSSIYADA TERAKT UYUSHTIRISHDI!
08:41
i'm so tired of talking about this..
10:00
Просмотров 27 тыс.
The 6 Design Patterns game devs need?
24:20
Просмотров 366 тыс.
Better Save/Load using Data Binding in Unity
18:47
Просмотров 12 тыс.
Harder Drive: Hard drives we didn't want or need
36:47
The Power of Scriptable Objects as Middle-Men
17:41
Просмотров 123 тыс.
So You Think You Know Git - FOSDEM 2024
47:00
Просмотров 1,1 млн
WebRTC Crash Course
1:10:06
Просмотров 226 тыс.
The Surgery That Proved There Is No Free Will
29:43
Просмотров 118 тыс.
O'ZBEK VA TOJIKLAR ROSSIYADA TERAKT UYUSHTIRISHDI!
08:41