Quick answer: Static fields are cleared on domain reload. Re-acquire references in OnEnable, or use [RuntimeInitializeOnLoadMethod] to re-init, or disable domain reload (with reset code).

A game uses a static cache pointing at a ScriptableObject config. After entering Play mode, the static is null — domain reload wiped it.

Why Statics Reset

Entering Play mode triggers a domain reload by default: the .NET domain is recreated, so all static fields revert to their default (null for references). This mirrors a fresh process start.

Re-Fetch in OnEnable

public class ConfigHolder : MonoBehaviour
{
    public GameConfig config;

    void OnEnable()
    {
        ConfigService.Current = config;   // re-populate the static
    }
}

OnEnable runs after every domain reload — a reliable place to repopulate statics from serialized references.

RuntimeInitializeOnLoadMethod

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Init()
{
    ConfigService.Current = Resources.Load<GameConfig>("GameConfig");
}

Runs once on play start. Good for loading a singleton config from Resources/Addressables.

Disabling Domain Reload

Project Settings → Editor → Enter Play Mode Settings: you can disable Reload Domain for faster iteration. But then you must manually reset statics in a [RuntimeInitializeOnLoadMethod(SubsystemRegistration)] method — otherwise state leaks between play sessions.

Verifying

Enter and exit Play mode repeatedly. The static reference is always valid at runtime. No null refs on the first frame.

“Domain reload wipes statics. Repopulate in OnEnable or RuntimeInitializeOnLoadMethod.”

If you disable domain reload for speed, audit every static field for leak-prone state — that’s the trade you’re making.