Friday, April 20, 2012

System.Serializable attribute annoyances in Unity3D



I recently discovered the [System.Serializable] attribute introduces an unfortunate quirk when used in Unity3d, which is very annoying to get around.  When you mark a class as Serializable, Unity will automatically instantiate an object for any field you define of that class type.  Even if you want that field to be null.  Take the following code:

[System.Serializable]
public class SerializableDataClass
{
    public int SomeValue = -1;
}

public class NormalDataClass
{
    public int SomeOtherValue = -1;
}

public class MyMonoBehaviour : MonoBehaviour
{
    // Will Never Be Null, not expected
    public SerializableDataClass DataObj1 = null;

    // Will Remain Null Until Assigned, as expected
    public NormalDataClass DataObj2 = null
}

Logically, you'd expect MyMonoBehaviour's DataObj1 and DataObj2 fields to initialize to null and remain null until assigned an object to reference.  Unfortunately this isn't the case, DataObj1 will automatically have an object created and assigned to it, even if you initialize it to null and try setting it to null in other areas like Awake()/Start()/Update().  This behavior becomes very disruptive if you have logic that triggers based on if DataObj1 != null.