ruk·si

⬜️ 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 or readonly.
  • 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[] where T is something Unity can serialize.
  • List<T> where T 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(); } }
    }
}