unity3d Implementation using RuntimeInitializeOnLoadMethodAttribute


Example

Since Unity 5.2.5 it's possible to use RuntimeInitializeOnLoadMethodAttribute to execute initialization logic bypassing MonoBehaviour order of execution. It provides a way to create more clean and robust implementation:

using UnityEngine;

sealed class GameDirector : MonoBehaviour
{
    // Because of using RuntimeInitializeOnLoadMethod attribute to find/create and
    // initialize the instance, this property is accessible and
    // usable even in Awake() methods.
    public static GameDirector Instance
    {
        get; private set;
    }

    // Thanks to the attribute, this method is executed before any other MonoBehaviour
    // logic in the game.
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void OnRuntimeMethodLoad()
    {
        var instance = FindObjectOfType<GameDirector>();

        if (instance == null)
            instance = new GameObject("Game Director").AddComponent<GameDirector>();

        DontDestroyOnLoad(instance);

        Instance = instance;
    }

    // This Awake() will be called immediately after AddComponent() execution
    // in the OnRuntimeMethodLoad(). In other words, before any other MonoBehaviour's
    // in the scene will begin to initialize.
    private void Awake()
    {
        // Initialize non-MonoBehaviour logic, etc.
        Debug.Log("GameDirector.Awake()", this);
    }
}

The resulting order of execution:

  1. GameDirector.OnRuntimeMethodLoad() started...
  2. GameDirector.Awake()
  3. GameDirector.OnRuntimeMethodLoad() completed.
  4. OtherMonoBehaviour1.Awake()
  5. OtherMonoBehaviour2.Awake(), etc.