- Home /
I have a class containing my settings/player stats. How would I serialize the whole class at once in order to save load?
So, I have a few scripts which serve as classes containing settings and player stats. I know how to save and load data by referencing every variable in a class one by one, but I want to save and load a whole class WITH its values at save time through serialization and binary formatting (you know, the classic). Now, I read one question which was answered that the class should be loaded as a game object, but I have no idea what to do... Do I reference the game object holding it and then save/load it? I have the player stats script on my character controller, so I don't think that loading a new game object from a file would be what I want, as I need it to copy over to that specific player game object.
In essence, let's say I have this for now:
public class SettingsScript : MonoBehaviour
{
public GUISettings GUISettings;
[Header ("Display settings")]
[Range (24, 144)]
public int FPS;
[Range (240, 2160)]
public int yRes;
public short RatioMode;
public string[] Ratios;
public short multX, multY;
//0 - 4:3, 1 - 16:9, 2 - 16:10, 3 - Custom
}
and on run time I have set some values. This script persists on a special game object that only holds modules like a transition effects script, GUI settings, map information container, etc. I would want to save this whole class in a file and then also load it all at once when loading, so with the least amount of hard-coding.
Ins$$anonymous$$d of a $$anonymous$$onoBehavior script, use a simple class to hold your settings. If you want to edit it via the inspector, make a seperate holder class that inherits from $$anonymous$$B and holds one instance of the settings class as a variable (don't forget the [System.Serializable] attribute). Now you can easily serialize the class instance and write it to a file via BinaryFormatter.
Here is the thing - all of my settings classes need to have $$anonymous$$onoBehaviour because the game can edit their values on the fly. That is the problem - I want to know if I can directly serialize a $$anonymous$$onoBehaviour class or at least without using a special clone class as a container and a middleman. I partially understand why you can't serialize $$anonymous$$onoBehaviour classes, but I need to only change the values, not references, and doing it with a container class and a function which transfers values seems redundant.
I don't understand why the way I suggested wouldn't work for you since it doesn't matter if the values are in the main body of a $$anonymous$$B script, or part of a class instance referenced by a variable inside the $$anonymous$$B script.
Nevertheless, you could also write SerializationSurrogates for your $$anonymous$$B scripts that should be serialies but that would also mean having to access each member directly.
Long story short: If you want to serialize, don't inherit from $$anonymous$$B.
Answer by tanoshimi · Aug 12, 2017 at 07:46 AM
This is what ScriptableObjects are for: https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects
ScriptableObjects are not serializable. It seemed like an ideal solution to my problem, however they act just like $$anonymous$$onoBehaviour when trying to serialize it.
You can serialize an instance of a non monobehaviour class IN a scriptable object, but that is not what I need, as it's basically the same to maintain as the container and copy function.
Answer by agray427 · Jan 15, 2018 at 07:29 PM
You do not want to use Scriptable Objects. Scriptable Objects are essentially config files that should not be changed at runtime. You should have any information that you want to persist be put into a class that does not inherit from MonoBehaviour. For instance, if I have a Player class that inherits from MonoBehaviour that handles controller input and stuff... It is what many who program consider a View. It's the visual side of a program. But it is not a Model, which is the data side of a program. So I would have another class called PlayerData that does not inherit from MonoBehaviour. PlayerData will hold nothing but pure data. It should not have any references to MonoBehaviour or ScriptableObjects inside it either, because they don't serialize. Then, when you want to save the data, you serialize the entire PlayerData file. When you want to load it, you load the PlayerData file. This one file will hold all of the information you have for each player. Here's the benefit of doing it this way. First off, you don't get errors about trying to serialize a Game Object or Scriptable Object. Secondly, if you do it right, all you need to do is instantiate the Player prefab, access the Player script on it, and load the Player Data and your player will be completely as it was. In your case, all of those Display Settings will need to go into a class of their own so it to can be serialized if it changes. The only thing you should have on your MonoBehaviour derived class is variables that are being tested, or those that differ from other instances of the same class and stored in different prefabs, but not variables that can change at runtime and need to persist. For instance, if I create an AI class, I might have AI difficulty be on the MonoBehaviour, and then save a prefab of AI for Easy, Medium, and Hard, with that value being different for each. But it doesn't change at runtime, especially not in a way that needs to persist. Hopefully this helped, but I have more reading you can do on the subject that can be found on a post in my blog which will even walk through the way you can serialize your data: https://graymattertutorials.wordpress.com/2018/01/15/serialization-with-json-net-in-unity-3d/
Your answer
Follow this Question
Related Questions
unity2d : BinaryFormatter files are not secure 1 Answer
Is There Any Way To Save A Variable Into a .txt file? 1 Answer
Save and load system not working please help 1 Answer
Google Cloud Save Data returns empty. 1 Answer
Using save options to create saves for toggle buttons, but won't compile! 1 Answer