<aside> ⚠️
Odin Serializer does not override basic Unity serialization! You must explicitly specify which fields will be serialized with Odin!
</aside>
[OdinSerialize] attribute[NonSerialized] attribute<aside> ⚠️
Do not serialize one field with both Unity and Odin!
It could lead to subtle errors and duplication of data in your asset.
</aside>
| Odin Serializer | Unity JSON | Full Serializer | Binary Formatter | JSON.NET | |
|---|---|---|---|---|---|
| Open Source | ✅ | ❌ | ✅ | ❌ | ✅ |
| Cross Platform | ✅ | ✅ | ✅ | ✅ | ✅ |
| Out-of-the-box Unity Support | ✅ | ✅ | ✅ | ❌ | ❌ |
| Supports Unity structs | ✅ | ✅ | ✅ | ❌ | ❌ |
| Binary Format | ✅ | ❌ | ❌ | ✅ | ❌ |
| JSON Format | ✅ | ✅ | ✅ | ❌ | ✅ |
| Merge-friendly data in Unity objects | ✅ | ❌ | ❌ | ❌ | ❌ |
| Interfaces | ✅ | ❌ | ✅ | ✅ | ✅ |
| Properties | ✅ | ❌ | ✅ | ❌ | ✅ |
| Polymorphism | ✅ | ❌ | ✅ | ✅ | ✅ |
| Generics | ✅ | ❌ | ✅ | ✅ | ✅ |
| Dictionaries | ✅ | ❌ | ✅ | ✅ | ✅ |
| Circular References | ✅ | ❌ | ✅ | ✅ | ✅ |
| Delegates | ✅ | ❌ | ❌ | ✅ | ❌ |
| Multi-dimensional arrays | ✅ | ❌ | ❌ | ✅ | ✅ |
| Extendable | ✅ | ❌ | ✅ | ✅ | ✅ |
| Renaming Members | ✅ | ✅ | ✅ | ✅ | ✅ |
| Renaming Types | ✅ | ✅ | ✅ | ✅ | ✅ |
| IL Optimized | ✅ | ➖ | ❌ | ❌ | ❌ |
| Supports .NET interfaces | ✅ | ❌ | ❌ | ✅ | ❔ |
| Supports .NET callback attributes | ✅ | ❌ | ❌ | ✅ | ✅ |
Inherit from SerializedMonoBehaviour or SerializedScriptableObject
public class YourMonoBehaviour : SerializedMonoBehaviour
{
[SerializeField]
private object SerializedPrivateField;
public object SerializedField;
[OdinSerialize]
public object SerializedProperty { get; set; }
}
If this doesn't work for you, for example, because you already have a specific base type you need to inherit from, it is very easy to implement the serialization yourself where you need it, by implementing Unity's ISerializationCallbackReceiver interface and using Odin's UnitySerializationUtility class.
[ShowOdinSerializedPropertiesInInspector]
public class CustomSerializedScriptableObject : ScriptableObject, ISerializationCallbackReceiver
{
[SerializeField, HideInInspector]
private SerializationData serializationData;
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
UnitySerializationUtility.DeserializeUnityObject(this, ref serializationData);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
UnitySerializationUtility.SerializeUnityObject(this, ref serializationData);
}
}
This is the complete code for a custom Odin-serialized MonoBehaviour:
[ShowOdinSerializedPropertiesInInspector]
public class CustomSerializedMonoBehaviour : MonoBehaviour, ISerializationCallbackReceiver, ISupportsPrefabSerialization
{
[SerializeField, HideInInspector]
private SerializationData serializationData;
SerializationData ISupportsPrefabSerialization.SerializationData
{
get => serializationData;
set => serializationData = value;
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
UnitySerializationUtility.DeserializeUnityObject(this, ref serializationData);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
UnitySerializationUtility.SerializeUnityObject(this, ref serializationData);
}
}