Search Unity

Saving and loading complex objects

Discussion in 'Scripting' started by SVKsuli, Feb 15, 2020.

  1. SVKsuli

    SVKsuli

    Joined:
    Mar 23, 2014
    Posts:
    62
    Hello, im just learning how to save and load game data and all tutorials i found are like create one script with few basic int or string properties and few lines of codes to save/load this data, but i never found anything about
    • how to do this with more complex gameobjects, (builded from many child objects with different components which could be changed in runtime like color in materials)
    • how to build scene back how it was last time,
    • how to manage to save dozens of different scripts (have all saveable data at one place or have copy of same code to save all scripts one by one)
    Im doing Sim City like game and i wonder how i going to save whole scene. I just need to save progress.
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    7,424
    Generally you just do these complex GameObjects the same as the simple ones, but you just have a lot more data to save. Come up with a serialization scheme for each script. Then in a "master" script on the GameObject and you have it call the serialization methods on all these other scripts, and packages it all up together. Then you have some system in your game which either finds all these GameObjects which need to be serialized, or just maintain a list of references to all these GameObjects. Then you have a method you call there, which goes through the entire list of GameObjects collecting all of their serialized data, and you package it all up into a single save file.

    When you restore the scene you basically reverse the process. You load all the data from disk. You go through and one by one recreate the GameObjects based on the saved data, and then you recreate the correct child objects and state of their scripts from the saved data.

    You can use your own custom save format, you can use text formats like JSON or even CSV, or whatever you want.
     
  3. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    782
    As a rule of thumb: divide and conquer. If you have one big problem you cannot solve, divide it into smaller problems until you can solve them. Solving all of the smaller problems equals solving the big problem.
    So if you have complex gameobjects with lots of children, then saving all the children, their data, and their relations equals saving the complex object structure.

    Building a scene back as it was before works the same. The state a scene is in is a combination of the positions or generally states of all objects. This also includes some custom data like unlocked doors, completed quests and so on. Saving and reconstructing this data, reconstructs your scene.

    Of course this is a lot of data, and you wouldnt want to copy tons of code. You can either attach a script with all the saving-options you need to every object, and have each object save and reconstruct its own data, or you create one SaveLoadManager type of object that takes case of the saving in one centralized location and gets taked to by every object that needs saving. Your saving solutioner would then offer the default options like SaveInt(), SaveFloat(), but also your custom methods like SaveIntArray() or SaveTransform() and so on.
    For the centralized approach, an object that wants to save data would call SaveLoadManager.SaveTransform("Player", transform), where the string indicates the object the data belongs to. The SaveLoadManager needs to keep track of this in order to return the correct data on SaveLoadManager.LoadTransform("Player");. For less unique data types an identifier would be required, such that you know what the, for example, integer represents.

    Also keep in mind that there are a lot of different ways to save data, from using PlayerPrefs, to writing it to your own database or file format.
     
  4. gaglabs

    gaglabs

    Joined:
    Oct 17, 2019
    Posts:
    26
    Also note, you cannot save GameObjects themselves. Rather, their data.
     
  5. SVKsuli

    SVKsuli

    Joined:
    Mar 23, 2014
    Posts:
    62
    So unity will not help me with this ? so i need to create some system around it so i will know what gameobject with how components to create and where ? Thats like twice as many work just to save data :(
    I dont have any idea how it must look like in code... But if this is only one way how to do it then i need just start with something simple to figure it out.
     
  6. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    782
    Yeah, start simple and figure it out. Unity cannot really help you with this, since it does not know what data you actually want and need to save. Some data is not necessary. So Unity could save everything, but that would just create huge files and loading times and would thus be a feature you'd need to rewrite yourself anyways.

    Start by writing a script that is attached to one gameobject with one arbitrary (example-)script. Then start saving information. You are only interrested in stuff that can change. In a transform, for example, you do not need to save the scale, unless things can be rescaled. You only need to save the position and rotation if those can be adjusted (so for a player, but not for a house). For custom scripts, ask yourself what is important. Internal variables most likely are not important to save, results and things that get accessed from the outside (or internal variables that affect those) are.
    For experimenting around take a look into PlayerPrefs, as it offers a quick way to save some data. You may or may not want to use a different system later on, but while you are trying to get a grasp of how saving and loading works, it's definitely sufficient.

    You should also take a look at what others did. Saving and loading is something the majority of games require, so there are bound to be quite a few tutorials, guides or assets already existing for it.
     
unityunity