- Home /
Which types are actually serializable? Is the documentation incorrect or am I?
So I'm writing my own serializing method for a quick little app I'm making and have been running into some issues.
I have a data structure called SaveableData which stores a whole bunch of information that is important to resuming the state when the game is loaded. The SaveableData class is what gets serialized to the hard drive by my Binary Formatter.
public class SaveLoad : MonoBehaviour
{
public string saveName = "Tech_Tree_01";
public string savePath = "/";
public void SaveData(SaveableData dataToSave)
{
string path = Application.persistentDataPath + savePath + saveName + ".dat";
FileStream userFile;
if(!File.Exists(path))
{//If the file isn't here, create it
userFile = File.Create(path);
userFile.Close();
}
//Then push all the data we need to save into this file
BinaryFormatter binaryFormatter = new BinaryFormatter();
userFile = File.Open(path, FileMode.Open);
binaryFormatter.Serialize(userFile, dataToSave);//This function serializes all our data to file
userFile.Close();
}
public void LoadData(string path)
{
SaveableData loadedData = new SaveableData();//This is the data that we're gonna load
if(File.Exists(path))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
FileStream userFile = File.Open(path, FileMode.Open);
loadedData = (SaveableData)binaryFormatter.Deserialize(userFile);
userFile.Close();
}
loadedData.LoadSaveableData();//After we have deserialized everything, load the data
}
SaveableData contains data of the following types: ints, floats, strings, rects, colors, and vector2s. When attempting to serialize this data, I get the following errors:
SerializationException: Type UnityEngine.Rect is not marked as Serializable.
SerializationException: Type UnityEngine.Vector2 is not marked as Serializable.
SerializationException: Type UnityEngine.Color is not marked as Serializable.
http://docs.unity3d.com/ScriptReference/SerializeField.html
According to the documentation, the following is serializable:
All classes inheriting from UnityEngine.Object, for example GameObject, Component, MonoBehaviour, Texture2D, AnimationClip.. - All basic data types like int, string, float, bool. - Some built-in types like Vector2, Vector3, Vector4, Quaternion, Matrix4x4, Color, Rect, LayerMask.. - Arrays of a serializable type - List of a serializable type (new in Unity2.6) - Enums
NOTE: I have properly placed the [System.Serializable] Attribute at the top of the classes. My current version is 4.5 Pro.
I've looked all over and I can't find anyone else having these issues. Where am I going wrong? Is the documentation incorrect or am I making a mistake?
I avoided this problem by creating workarounds for Unity-specific variables (3 floats for a Vector3 and so on), but while doing research for my own serialization script I got the impression that only if using Unity's built-in serializer can you serialize those classes, BUT the serialization system is primarily for non-runtime work (editor extensions and such).
This might just as well be just a whole bunch of baloney because I didn't dig too deep into the matter before deciding on workarounds, but it's how I understood the pieces of information I saw.
I'm hoping this is not the case, as I would very much like to avoid doing that. It would make large data structures look VERY sloppy
The class BinaryFormatter is a pure c sharp system to serialize data but the link you are posting is from an internal unity serialization method. These two things don't work together. This is the correct documentation for your method: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx
It can only use types that include the ISerializable interface e.g. the unity Rect class doesn't use this interface so you can't serialize it with this method. Sadly, you can't change unity classes so you have to serialize its values separately or using custom made structs/classes for this process
Answer by BadAssGames · Oct 08, 2014 at 05:56 AM
Well, Devluz pretty much answered this.
For anyone else having similar issues, the unfortunate solution I chose was to write a rather simple, but annoying function. This It looks something like this: (Pseudocode)
System.Collection.Generic.List<float> floatList;
public void SerializeData()
{
foreach(DataType data in myData)
{
//loop through and grab all the data as a float
//then add that float to the float list
}
}
public void DeserializeData()
{
foreach(float number in floatList)
{
//loop through and grab the floats and convert them
//back to their original data types *sigh*
}
}
I sughgest looking into Unity Serializer, specifically the LevelSerializer.cs script to see how whole gameobjects components and all, can be serialized and deserialized.
Answer by mikest · Dec 09, 2015 at 12:38 AM
If using the C# binary formatter, I think something like this is easier to implement and use than the float array. I have also used a similar technique to serialize Vector3's in Unity.
[System.Serializable]
public class SerializableColor {
public float R;
public float G;
public float B;
public float A;
public SerializableColor (Color color) {
R = color.r;
G = color.g;
B = color.b;
A = color.a;
}
public Color GetColor () {
return new Color(R, G, B, A);
}
}
Answer by Voxel-Busters · Aug 08, 2015 at 10:05 PM
Serialization of Unity objects are not directly possible using Binary Formatter. Check this post for more info.