# Serialize DataObjects

{% hint style="info" %}
Databrain supports all common Unity types + custom classes
{% endhint %}

All DataObjects which have been added to the runtime DataLibrary can be serialized. They will not be serialized automatically as you will have to define the fields that should be serialized and added to the save file.

1. Make sure your DataObject has been added to the runtime DataLibrary:

{% content-ref url="add-data-objects-at-runtime" %}
[add-data-objects-at-runtime](add-data-objects-at-runtime)
{% endcontent-ref %}

2. Use the <mark style="background-color:orange;">\[DatabrainSerialize]</mark> attribute on all serializable fields. Like this:

```csharp
public class EnemyData : DataObject
{
    public GameObject prefab; //not serializable   
    
    // This will serialize health
    [DatabrainSerialize]
    public int health;
    // This will serialize strength
    [DatabrainSerialize]
    public float strength;
}
```

3. That's it! Databrain does now all the hard work for you.

## Serializing by using the serializable class

It is also possible to create a serializable class which only contains the serializable fields. This class can then be constructed and passed on via the <mark style="background-color:orange;">SetSerializedData</mark> and <mark style="background-color:orange;">GetSerializedData</mark> overridable methods. This can be useful when implementing custom serialization for non-serializable data types like Texture2D to bytes, for example.

Let’s assume we have this DataObject Class:

```cpp
public class EnemyData : DataObject
{
    public GameObject prefab; //not serializable
    public int health;
    public float strength;
}
```

We now have to create an additional runtime class derived from **SerializableDataObject**.

```cpp
public class EnemyData : DataObject
{
    public GameObject prefab; //not serializable
    public int health;
    public float strength;
}

// Runtime Dataobject class
public class RuntimeEnemyData : SerializedDataObject
{
    public int health;
    public float strength;
    
    // For serialization we need to add a parameterless default constructor
    public RuntimeEnemyData(){}
    
    // Use the constructor to only assign serializable data
    public RuntimeEnemyData (EnemyData _data)
    {
        this.health = _data.health;
        this.strength = _data.strength;
    }
}
```

As you can see, the runtime class looks very similar to the EnemyData object class. We're just using its constructor to pass the original data to the runtime data.

As a last step, we now have to override two methods in the DataObject to set and get the data back. Modify the script in the following way:

```csharp
public class EnemyData : DataObject
{
    public GameObject prefab; //not serializable
    public int health;
    public float strength;
    
    // Return the serializable data object
    public override SerializableDataObject GetSerializedData()
    {
        var _runtimeEnemyData = new RuntimeEnemyData(this);
        return _runtimeEnemyData;
    }
    
    // Called after loading of json file.
    // Set back the data.
    public override void SetSerializedData(object data)
    {
        health = (data as RuntimeEnemyData).health;
        strength = (data as RuntimeEnemyData).strength;
    }
}

// Runtime Dataobject class
public class RuntimeEnemyData : SerializableDataObject
{
    public int health;
    public float strength;
    
    // For serialization we need to add a parameterless default constructor
    public RuntimeEnemyData(){}
    
    // Use the constructor to assign the data
    public RuntimeEnemyData (EnemyData _data)
    {
        this.health = _data.health;
        this.strength = _data.strength;
    }
}
```

Your DataObject is now ready to be serialized by Databrain.

{% hint style="info" %}
Please note: For serialization, a parameterless default constructor is required for the runtime SerializableDataObject
{% endhint %}
