Joys of Serialization…. in Unity….

So, serialization is super awesome…. Especially Binary Serialization, where you can save a file that cannot be edited outside your Application.

However, when attempting to use Binary Serialization in UNITY, it causes a whole mess of problems. For example, if you want to use Vector3s, Colors, etc., you must create your own float3 (or equivalent) so that you can serialize it, because Unity doesn’t have them as Serializable objects.

 

So, I decided to write up a basic text based tutorial on how I dealt with this:
Note: [System.Serializable] is KEY!

 

[System.Serializable]
public class ship {
[System.Serializable]
public class shipParts {
public string name;
public float3 position;
//…. more position and color data stored here as float3’s
}

public string name; //Information about the ship stored here
public List parts;
}

[System.Serializable]
public struct float3
{
public float3(float X, float Y, float Z)
{
this.x = X;
this.y = Y; // constructor for X Y Zs.
this.z = Z;
}

public float3(Vector3 vec3)
{
this.x = vec3.x;
this.y = vec3.y; // constructor for vector3s
this.z = vec3.z;
}

public float3(Color col3)
{
this.x = col3.r;
this.y = col3.g; // constructor for colors
this.z = col3.b;
}

public float x;
public float y; // variables
public float z;
};

As you can see here, I had to create a custom struct, just to store out the positions, then, when I re-instantiated, I had to create a new Vector3/Color and put in the values the float3.x, float3.y, and float3.z values.

Now, that I got that into place, time to serialize!

//……… code

var parts = new List();

//foreach part in scene, we need to create a part for it
foreach (var inSceneMesh in _inSceneMeshes)
{
var j = new ship.shipParts();
j.name = inSceneMesh.name.Split(‘(‘)[0];
j.position = new float3(inSceneMesh.position);
//more information about the part to store….
parts.Add(j);
}

//create our ship 🙂
var ship = new ship();
ship.parts = parts;
ship.name = _shipName;

//create a directory to save it in, if it doesn’t exist…
if (!Directory.Exists(string.Format(@”{0}\Saves\Ships”, Application.dataPath)))
Directory.CreateDirectory(string.Format(@”{0}\Saves\Ships”, Application.dataPath));

//open up a stream, that allows us to write data
var stream = new FileStream(string.Format(@”{0}\Saves\Ships\{1}.ship”, Application.dataPath, ship.name), FileMode.Create, FileAccess.Write, FileShare.Write);
//create a Binary Formatter, and serialize the data into a Binary format
//then close stream
var formatter = new BinaryFormatter();
formatter.Serialize(stream, ship);
stream.Close();

//……… code

Now that we have it all serialized, we can then go and de-serialize it! Yeah! Almost done!

//…….. more code
using (var stream = new FileStream(shipFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var formatter = new BinaryFormatter();
var obj = (ship)formatter.Deserialize(stream);
if (GUILayout.Button(obj.name))
{
ship.currentShip = obj;
Application.LoadLevel(“Builder”);
}
}
//…….. more code

As you can see, de-serialization is much easier, but that isn’t the end of it, that is just making it so that we can load it up in our Builder scene, so that we can take the info and stick it in, but you should be able to figure it out from there. 🙂 All you have to do is instantiate each shipPart, and and set its properties, which are stored in the ship.currentShip static variable, which holds a ship….

Hope this helps all of y’all!

Advertisements
    • Aleks
    • March 31st, 2011

    Looks awesome, cant wait to try it out.
    3 Questions tho:
    Is this in C#?(Looks like b/c of the syntax, but wanted to make sure)
    Can you Serialize ArrayLists?
    and
    How does adding more classes into a Unity script work?(Or are they all supposed to stay separate?)

  1. Yes it is C#.

    I do not think you can Serialize ArrayLists, but I am not 100% sure on that, as I don’t use them.

    You have to separate all classes into separate scripts if they are monobehaviours, otherwise you end 1 class declaration and put the next declaration.

    • Aleks
    • April 1st, 2011

    Thank you very much. I will run with this and see where it goes. I do wish unity had a better build in save system though. Ah well.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: