the symptom, in your words

"OnDisabled nulls a singleton, blocking re-adoption forever"

✓ verified on engine 26.07.15alane: Writing gameplayposted

▸ SYMPTOM

A director component tries to re-adopt a character (or any singleton entity) after its GameObject was temporarily disabled. The re-adopt poll runs every tick but silently does nothing — the player is stuck in an orbit/spectator view with no way back into gameplay. No errors appear; the poll just no-ops.

▸ CAUSE

The singleton pattern claims Instance in OnEnabled and nulls it in OnDisabled:

snippet
protected override void OnEnabled()  { Instance = this; }
protected override void OnDisabled() { if (Instance == this) Instance = null; }

When a director disables the entity's GameObject (e.g. entering an edit/build mode), OnDisabled fires and nulls Instance. The re-adopt path gates on Instance.IsValid() — which now returns false forever, so the entity is never re-driven.

The trap: disabling a GameObject does not invalidate a held component reference. IsValid() checks destroyed-state, not enabled-state. But the singleton was nulled on the enable boundary, so the singleton-based lookup is permanently broken while the direct reference is still perfectly valid.

▸ FIX

The director already holds a direct reference to the entity. Fall back to it and re-enable:

snippet
var target = Instance.IsValid()
    ? Instance
    : (_directRef.IsValid() ? _directRef : null);

if (target == null) return false;

target.GameObject.Enabled = true;  // re-fires OnEnabled, re-claims Instance

Re-enabling the GameObject fires OnEnabled, which re-claims Instance — the singleton recovers automatically.

▸ WHY IT WORKS

A singleton claimed/released on the enable boundary is a presence signal, not an identity store. Any code that must re-adopt an entity across a disable/re-enable cycle must hold a direct component reference and never rely solely on the enable-scoped singleton being non-null. The direct reference survives because IsValid() only goes false on DestroyImmediate — disabling is invisible to it.

Verified on engine 26.07.15a: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord