⬜️ Unity - Serialization
Updated at 2016-10-30 10:52
Unity serializes everything as YAML files to the file system.
C# class field is serialized if:
- Field is
public
, or has[SerializeField]
attribute. - Field is not
static
,const
orreadonly
. - Field's type is a type that Unity can serialize.
Unity can serialize the following field types:
- Custom non-abstract classes with
[Serializable]
attribute. - Custom structs with
[Serializable]
attribute. - References to objects that derive from
UntiyEngine.Object
. - Primitive data types (
int
,float
,double
,bool
,string
, etc). T[]
whereT
is something Unity can serialize.List<T>
whereT
is something Unity can serialize.
Unity doesn't support serialization of null
for custom classes. This will cause a lot of unnecessary allocations for cases where there is recursive objects to serialize.
class Test : MonoBehaviour
{
public Trouble t;
}
[Serializable]
class Trouble
{
public Trouble t1;
public Trouble t2;
public Trouble t3;
}
Unity serialization doesn't support polymorphism of custom classes. You can use polymorphism with MonoBehaviours and ScriptableObjects though.
[Serializable]
class Animal { public string name; }
class Dog : Animal { }
class Cat : Animal { }
class Zoo : MonoBehaviour { public List<Animal> animals; }
var a = new Dog();
var b = new Cat();
Zoo.animals.Add(a);
Zoo.animals.Add(b);
// These both will become Animals on deserialization.
You can define serialization strategy yourself. If Unity's serializer doesn't support some field type, you can use the following callbacks.
using UnityEngine;
public class AssetBundleCode : MonoBehaviour
{
private List<SerializableNode> serialized;
[Serializable]
private struct SerializableNode
{
public string interestingValue;
public int childCount;
public int indexOfFirstChild;
}
// Serialization doesn't happen on the main thread so
// don't use anything from Unity API.
private void OnBeforeSerialize() { /* populate serialized */ }
private void OnAfterDeserialize() { /* read from serialized */ }
}
The Serializable
attribute lets you embed a class with sub properties in the inspector.
using System;
using UnityEngine;
namespace Company.MyGame
{
[Serializable]
public class Person
{
public string name;
public int age;
}
}
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
namespace Company.MyGame
{
public class World : MonoBehaviour
{
[SerializeField]
private List<Person> people = new List<Person>();
public ReadOnlyCollection<Person> People { get { return people.AsReadOnly(); } }
}
}