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.

3 comments:

  1. Interestingly, if you set SerializableDataClass to private, then it can be null. However, if you set it to private, and modify a script while the game is running in the editor, and then go back to the Editor to re-load all of the scripts/DLLs, the reference will get instantiated at that point, and will no longer be null. The inconsistency is incredibly annoying.

    How are we supposed to make great games without null references?

    If you have a good work around for this ridiculous behavior, please let us know.

    ReplyDelete
  2. Great article ...Thanks for your great information, the contents are quiet interesting. I will be waiting for your next post.
    Unity3d game development

    ReplyDelete