Search Unity

Serialization, MonoBehaviour constructors and Unity 5.4

June 6, 2016 in Technology | 3 min. read
image01
image01
Topics covered
Share

Is this article helpful for you?

Thank you for your feedback!

Starting with Unity 5.4, we have added new errors that are displayed when calling the Unity API from constructors/field initializers and during deserialization (loading). The purpose of these errors is to make the Unity API usage requirements clear and avoid any side effects incorrect usage might have.

The majority of the Unity API should only be called from the main thread, e.g. from Start/Update/etc on MonoBehaviour. Similarly, only a subset of the Unity API should be called from script constructors/field initializers, like Debug.Log or Mathf. As Unity will invoke constructors when creating an instance of a class during deserialization (load), which might run on a non-main thread.

These requirements were not strictly enforced in versions of Unity prior to 5.4. Which could lead to crashes, race conditions and issues that were hard to diagnose and reproduce.

In Unity 5.4, the new errors will in most cases not throw a managed exception and will not interrupt the execution flow of your scripts. This approach has been taken to reduce the amount of friction caused by upgrading your projects to Unity 5.4. These errors will throw a managed exception in a future release of Unity. We recommend that you fix these errors (if any) in your project when upgrading to 5.4.

The new errors are documented in the “Script Serialization Errors” section on the Script Serialization page in the manual.

Let’s have a look at the new serialization errors in some common scenarios and how to fix them.

Calling Unity API from constructor/field initializers

When Unity creates an instance of your MonoBehaviour/ScriptableObject derived class, it calls the default constructor to create the managed object. When this happens, we are not yet in the main loop and the scene has not been fully loaded yet. Field initializers are also called when calling the default constructor of a managed object. Calling the Unity API from a constructor is considered unsafe for the majority of the Unity API.

Examples:

public class FieldAPICallBehaviour : MonoBehaviour
{
   public GameObject foo = GameObject.Find("foo");
}
image01
public class ConstructorAPICallBehaviour : MonoBehaviour

{
   ConstructorAPICallBehaviour()

   {
       GameObject.Find("foo");
   }

}
image00

In these case we will get the the error “Find is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call in in Awake or Start instead. ...”. The fix is to put the call to the Unity API in MonoBehaviour.Start.

Calling Unity API during deserialization (loading)

When Unity loads a scene, it recreates the managed objects from the saved scene and populates them with the saved values (deserializing). In order to create the managed objects, the default constructor for the objects must be called. If a field referencing an object is saved (serialized) and the object default constructor calls the Unity API you will get an error when loading the scene. As in the previous error, we are not yet in the main loop and the scene is not fully loaded. This is considered unsafe for the majority of the Unity API.

Example:

public class SerializationAPICallBehaviour : MonoBehaviour

{
   [System.Serializable]
   public class CallAPI
   {
       public CallAPI()
       {
           GameObject.Find("foo");
       }
   }

   CallAPI callAPI;
}
image02

Here we get the error “Find is not allowed to be called during serialization, call it from Awake or Start instead.” Fixing this issue requires us to refactor the code to make sure that no Unity API calls are made in any constructors for any serialized objects. If it is necessary to call the Unity API for some objects, then this must be done in the main thread from one of the MonoBehaviour callbacks, such as Start, Awake or Update.

Feedback

If you have any comments, questions or general feedback on these errors, you can post them here in this “Script Serialization Errors Feedback” thread on the Unity 5.4 beta forums.

June 6, 2016 in Technology | 3 min. read

Is this article helpful for you?

Thank you for your feedback!

Topics covered