I am adding a save function to my game and I have been lead to “serialization”, some of the variables I want to save are Color32 variables but seemingly unity didn’t make that serializable for some reason. It would be a massive headache to do something along the lines of saving each Color32 as 3 separate “r” “g” “b” int variables as I have multiple variables used in several subroutines that I really don’t want to change all of. Is there anything I can do with it?
This is something I’ve ran into with other types before such as Vector3 (for a while there unity kept attaching/removing the serializable attribute from this struct with every few releases).
What serialization engine are you using?
The built in Unity one’s should have support for Color32 out of the box. It’s serializable in the editor, so it’ll serialize. This means that JsonUtility.ToJson and FromJson should work (I haven’t tested… but it should).
Now if you’re using a 3rd party one. This changes things.
I believe Newtonsoft will just serialize things even if not marked as serializable. If it’s not doing it, it’s likely a configuration thing.
Other serializers, including newtonsoft, have a way to inject supported types. For example the Microsoft .net serializer uses what is called the “SurrogateSelector” and “Binder” to both bind types and format types when serializing.
I think newtonsoft’s is called “converter”.
Anyways… what serialization engine are you using?
@lordofduct I just found a guide online for this, I do not know what the serialization engine is, is that something you can glean from this code?
public void SaveFileInput()
{
SaveFile(PauseScreen.GetComponentInChildren<InputField>().text);
}
public void SaveFile(string name)
{
string destination = Application.persistentDataPath + "/saves/" + name + ".dat";
FileStream file;
if (File.Exists(destination)) file = File.OpenWrite(destination);
else file = File.Create(destination);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(file, grid.GetArray());
file.Close();
}
You’re using BinaryFormatter, which is part of Microsoft’s built in System.Runtime.Serialization engine. Which means you’d use the ISerializationSurrogate approach.
Furthermore… BinaryFormatter is considered NOT SECURE.
…
Instead of using BinaryFormatter. You should check out serializing to json (json being a very common format out there having that added benefit).
You can try out the built in JsonUtility:
this gets you very simple support
Alternatively you can tryout the Newtonsoft Json.Net project which is way more robust:
JSON .NET For Unity | Input Management | Unity Asset Store
NOTE - I can not speak for that specific asset store project. Json.Net is actually a non-unity affiliated thing found here:
Json.NET - Newtonsoft
Getting it into unity isn’t exactly straight forward, and the packages/asset store things that are unity related are just 3rd parties doing that leg work on your behalf.
Thanks for the info, I’ll check it out tomorrow
So I have tried using JsonUtility however I found it does not easily support arrays, see here.
That meant that this did not work:
public void SaveFile(string name)
{
string destination = Application.persistentDataPath + "/saves/" + name + ".json";
File.WriteAllText(destination, JsonUtility.ToJson(grid.GetArray()));
}
I tried this, which I thought it meant but clearly I am still doing something wrong here, what am I supposed to do?
[Serializable] public class TileArrayWrapper
{
Tile[,] array;
public TileArrayWrapper(Tile[,] array)
{
this.array = array;
}
}
public void SaveFile(string name)
{
string destination = Application.persistentDataPath + "/saves/" + name + ".json";
File.WriteAllText(destination, JsonUtility.ToJson(new TileArrayWrapper(grid.GetArray())));
}
Before when I said:
I meant that JsonUtility uses the built in serialization. This means it has the same restrictions as the serialization used for say your assets (what shows in the editor).
This means you must follow the same rules as that. So like 2d arrays aren’t supported, just like how they’re not in the editor.
There is another limitation (which is inherent to the unity serialization system, it’s just there you never run into it incidentally because everything serialized is rooted by a UnityEngine.Object of some sort).
The root object must be that… an object.
I know, json supports string/int/array as the root.
But unity doesn’t like it. The root MUST be an object (so like a class/struct).
So if you want to serialize an array you must create some type to root that array inside.
public class Token
{
public string[] Values;
}
In your case you can flatten your array and stick it in some class if you want.
OR
You can use Newtonsoft Json.Net which is more robust, like I said before.
But again, there are ALWAYS limitations to serialization. Rules that must be followed. It’s best to consult the documentation for whatever serialization library you decide using. This is why I linked to the documentation behind each library/engine I described.
@lordofduct Did you read my comment? I did put the array in a new class, but it still returned a blank json.
That was just added data, me pointing out other limitations of the serializer you chose.
My main point is that 2d arrays aren’t supported.
Another limitation to point out… private fields aren’t serialized unless marked with the [SerializeField] attribute:
These limitations pertain to JsonUtility in Unity. If you use say newtonsoft json.net, the limitations are different and you must consult that documentation instead.
I have finally got this to work completely with the Newtonsoft json.net. It seems the built in tools are just pretty rubbish.