Unity 2018 and PlayerLoop

Introduction

Before Unity 5.X (specifically 5.0), control over the application lifecycle was basically nonexistent. For application startup/initialization code you could’ve created a script that was sorted earliest in the Script Execution Order window and used Awake, but you would’ve ran into issues. An object with that script would need to exist in any scene that required that initialization code to run, a state that is really difficult to maintain while in the editor. It’s too easy to forget that object needs to be around, and that functionality needs to be explained to other developers working on the project.

With Unity 5.0 we were provided RuntimeInitializeOnLoad, an attribute placed on a static function which is then executed automatically at runtime consistently. Its a foolproof way of ensuring that some code always executes, regardless of scene setup. In 5.2 an optional argument in form of the RuntimeInitializeLoadType enum was added, allowing developers to decide if the marked function should execute before or after the initial scene is loaded (before the Awake message is sent). With this single feature it suddenly became viable to use Unity without scenes, slightly closer to using a game framework, such as MonoGame.

However, the systems that are updated each frame (some more often) were still out of reach. These systems are otherwise known as the main/game update loop. Systems could not be disabled for performance, reordered for preference, and, most importantly, new arbitrary systems could not be added into the Update loop. Of course you could always use functions like Update, FixedUpdate and LateUpdate to hook into the built in update systems, but these always occurred inbetween Unity’s internal systems, beyond user control.

With Unity 2018.1, the PlayerLoop and PlayerLoopSystem classes and the UnityEngine.Experimental.PlayerLoop namespace have been introduced, allowing users to remove and reorder engine update systems, as well as implement custom systems.

(more…)