"OnDisabled nulls a singleton, blocking re-adoption forever"
▸ 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:
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:
var target = Instance.IsValid()
? Instance
: (_directRef.IsValid() ? _directRef : null);
if (target == null) return false;
target.GameObject.Enabled = true; // re-fires OnEnabled, re-claims InstanceRe-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.