Unity Tip: Don’t use your first scene for global Script initialization.

 

I’ve noticed that a lot of projects online seem to use the first scene as a means of initializing global systems.

Why this is bad
Doing this means you are making yourself more dependent on your initialization scene.
I’ve seen a person streaming online, loading in the first scene countless times. Going from
Intro (Load a lot of stuff) -> Main Menu -> Level Select -> Your Level.

If you just want to test your scene, then this can become very tedious over time.
Making a game takes a lot of time, it is important to invest in making your iteration process quick and easy.

The solution
I’m happy to tell you there is a easy solution for this problem, using the [RuntimeInitializeOnLoadMethod] attribute.
In this case I’m going to demonstrate a way to have a prefab in your project that always loads first.

Create a prefab called ‘Main’ within your Resources folder, and attach this script to it.
Attaching the script is not mandatory, but in case you want to extend it in any way you can choose to do so.
Being able to set inspector fields can be beneficial, which is why the sample below still inherits from MonoBehaviour.

public class Main : MonoBehaviour
{
// Runs before a scene gets loaded
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void LoadMain()
{
GameObject main = GameObject.Instantiate(Resources.Load("Main")) as GameObject;
GameObject.DontDestroyOnLoad(main);
}
// You can choose to add any "Service" component to the Main prefab.
// Examples are: Input, Saving, Sound, Config, Asset Bundles, Advertisements
}
view raw Main.cs hosted with ❤ by GitHub

This script will ensure the prefab gets loaded before anything else.
This means you can attach any Service/GameObject to the prefab, and it will be guaranteed to load first.
Eliminating the possibility of any racing conditions. And the benefit of the services always loading, no matter what scene gets loaded.

A use example. For instance I want to use Graphy, A free performance monitoring tool.
Now I can just add graphy to the Main prefab, and it works in all scenes, even new ones.

One thing to keep in mind: Don’t reference any big assets within the Main prefab. As all references are also stored within the Resources folder. If you want to have some kind of asset loading system, I would recommend looking into the Adressables package or Asset Bundles.

What do I use this solution for?

I generally like to create service classes that are available before any scene is loaded.
For instance, to make sure that:
Config -> Setup global settings for game, store global configurations (Like volume)
Saving -> Initializing the save system
Audio -> Initializing a audio system. Being the fact that it is a prefab, it easily allows me to reference a Mixer
Input -> Initializing, configuring Rewired a plugin that makes it easy to get input on any platform.
I use it to add input support for mobile games. Including Masked.