Bootstrapping a Unity game at runtime is straightforward — you specify a start scene, do initialization there, and then load a title scene. But things get trickier when you're working inside the editor. What if you want to test a specific scene directly, yet still run essential bootstrapping code to initialize global state? I recently found a clean — and surprisingly simple — solution while working on my deck-building game Rabanaz. In this article, i’ll explore different mechanisms for Unity bootstrapping and show you how to combine them for a seemless editing experience.
Bootstrap here refers to everything prior to the first scene being “run”. It’s part of the overall startup process for the game. Don’t worry where bootstrapping ends, and the rest of the startup begins. Community members use “boot,” plus numerous similar terms, seemingly without distinction. Unity’s docs sometimes say “starting up and loading the first scene”.
If you just want the solution, then just jump the “Implementation” section.
First Scene is Start Scene
The first mechanism offered by Unity to control startup is the scene list. The startup scene is simply the first item in this list. This will typically be a bootstrap scene, often called the start scene, loader, or similar. This scene does some basic setup tasks and then switching to the real start scene, which is likely a game menu. You might have an intermediate scene here, the first one does minimal loading, and the second displays logos and loads the title screen.
This mechanism is unavoidable. The first listed scene always loads first. Because the decision to load this scene happens before any code runs, you cannot intercept it.
When you press play in the editor, you want to first load this scene, then load the scene you’re editing. It’s a common request, which makes it confusing why it’s hard to accomplish.
RuntimeInitializeOnLoadMethod
The RuntimeInitializeOnLoadMethod attribute marks static functions to be run at specific points during the startup process. This is a standard approach to run code prior to the first scene.
There are several values here, with BeforeSceneLoad often referenced in docs and forum posts. This is where you can initialize global variables that the scenes will need.
I’d been using a BeforeSceneLoad method to load an additive scene into my games, among setting up other systems. This additive scene contains all the global components, such as input handlers, event systems, audio systems, my pop-up handlers, and more. These components are essential for every game scene.
The problem is that my additive scene still loads after the start scene. If any component in the start scene has an Awake function that needs my global initialization, it’ll fail. The additive scene’s Awake is called after the start scene. Mostly, I’ve been able to workaround this, by not relying on other components during Awake. Yet it became increasingly problematic.
There is also BeforeSplashScreen which happens prior to the first scene loading, before the splash screen. Nonetheless, if you load an additive scene here, it’s Awake will still be called after awaking the first scene. Perhaps there’s a way to swap out the start scene, but I could not find it.
EditorSceneManager.playModeStartScene
When you press play in the editor, EditorSceneManager.playModeStartScene can override which scene loads. At first it sounds like what you’d want, but it’s not enough. What scene should you use? You want to run your bootstrap scene, but it will then load the title screen, not the one you’re editing.
Unity’s example for this property is an editor window with a dropdown list to select the scene to run. This might be useful when you have several entry-point scenes and always wish to start via one of them. But it feels limited.
Other references detailed an unusual editor loading and saving process for specific scenes, a technique that seemed prone to errors. I don’t want to change the scene I’m editing.
However, what if I create a boot scene that can load any other scene? This would be something that works. But how can I identify which scene is being edited? And how do I convey this to the boot scene?
Combining with the current scene
You can track the current scene, and set the playModeStartScene property at the same time. Add a handler to EditorApplication.playModeStateChanged, which is called whenever the play mode changes in the editor. The state change ExitingEditMode happens prior to the entry into play mode.
When you get this callback, call EditorSceneManager.GetActiveScene to determine which you’re editing. Also set playModeStartScene to your bootscene here. I do this conditionally, since it lets me bypass my bootstrap scene for certain test scenes.
You still need to tell your bootstrap scene which scene it should load. I still haven’t found a way for an editor component to communicate directly with a play-mode component — this would be invaluable for debugging. There is another technique I already use for debugging, PlayerPrefs. My game’s test configuration uses numerous properties.
The scene reference, a simple string, fits easily into PlayerPrefs. It’s one of the few systems that’s easy to interact with from both the editor and play components. Set a string property to the name of the scene. I used a property called BootSceenFirstScene. Then load that in the boot scene.
All together, this gives you what you want: when you press play mode, Unity will load your bootstrap scene first, then automatically transition to the scene you are editing. Best of luck refining your own bootstrapping process.
Implementation
The two important pieces of code here are the boostrap scene code, which I call BootSceneDriver and the editor code, which I call EditorInit. I have them defined in the same file. This may require adjustments; I replaced a tiny bit pf project-specific code with untested generic code.
#if UNITY_EDITOR using UnityEditor; using UnityEditor.SceneManagement; #endif using UnityEngine; using UnityEngine.SceneManagement; public class BootSceneDriver : MonoBehaviour { void Awake() { // I put all my global components in a separate SystemScene, which makes it // easy to load it all additively. SceneManager.LoadSceneAsync("Assets/Scenes/SystemScene.unity", LoadSceneMode.Additive); } void Start() { var startScene = "Assets/Scenes/StartMachine.unity"; // I only use scene redirection while in the editor, // but you may find it useful for debugging compiled builds too (just edit the playerprefs manually) #if UNITY_EDITOR var start = PlayerPrefs.GetString("BootSceneFirstScene", null); if( start != null ) { startScene = start; } #endif SceneManager.LoadSceneAsync( startScene, LoadSceneMode.Single); } } #if UNITY_EDITOR [InitializeOnLoad] public class EditorInit { static EditorInit() { // I reference the desired boot scene directly. This is the same as the first one in my scene list, // but the direct reference provides a way to provide an in-editor specialized one if desired bootScene = AssetDatabase.LoadAssetAtPath<SceneAsset>("Assets/Scenes/BootScene.unity"); if( bootScene == null ) { Debug.LogError("missingbootscene"); } EditorApplication.playModeStateChanged += OnPlayModeStateChanged; } static void OnPlayModeStateChanged(PlayModeStateChange state) { if (state == PlayModeStateChange.ExitingEditMode) { var activeScene = EditorSceneManager.GetActiveScene(); PlayerPrefs.SetString("BootSceneFirstScene", activeScene.path); // When testing Unity features I don't want the boot scene, or system scene used, // so I allow a normal, direct start of the edited scene EditorSceneManager.playModeStartScene = activeScene.path.Contains("Tests/") ? null : bootScene; } } } #endif





