tag

#lifecycle

11 items (11 fixes)

fixes
26.07.22
"A public Reset() on a Component silently shadows the engine's Component.Reset()"

Naming a Component method `public void Reset()` compiles clean and silently hides the engine's own `Component.Reset()`. The only signal is a CS0114 warning, which `dotnet build -v q` never prints. Green is not the same as warning-free: pick a different name (ResetState, Clear) unless you deliberately mean to hook the lifecycle method.

26.07.08e
"Edit-mode Destroy() is deferred: scene queries return stale objects"

GameObject.Destroy() in edit mode is deferred; a query fired right after returns the previous build's objects.

26.07.22
"Freeze a physics actor by going kinematic, not by destroying its Rigidbody"

Turning a composite physics actor into static scenery by destroying its Rigidbody silently kills every child system that keyed its own liveness off that body. Set MotionEnabled = false instead: the body stays alive, dependents keep ticking, and a kinematic body reads zero delta-v for free.

26.07.22
"GameObject.Destroy() is deferred: a destroyed object still holds its exclusive claims for the rest of the frame"

GameObject.Destroy() is deferred to the end of the frame, so an object you just destroyed still exists, still answers, and still holds any exclusive claim it owns (IsMainCamera, a singleton slot, a registry entry) for the rest of that frame. Clear exclusive claims on the outgoing owner BEFORE calling Destroy, and never read a leak census in the same frame as the teardown it checks.

26.07.15a
"Idempotent world rebuild needs DestroyImmediate, not Destroy"

Deferred Destroy() leaves the old code-built world overlapping the fresh one for a frame: use DestroyImmediate for teardown before rebuild, and pair it with a recipe hash for belt-and-suspenders join verification.

26.07.08e
"Joining client's static state wiped by networked scene handoff"

A joining client's static join state (invite code, mode, attempt ID) gets wiped by the networked scene handoff: the bootstrap's OnEnabled resets statics before the join handshake uses them.

26.07.08e
"Null check on a destroyed GameObject still NREs: use IsValid()"

A cached Component/GameObject reference guarded with == null still throws NullReferenceException after the object is destroyed: only IsValid() catches destroyed objects.

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

A singleton claimed in OnEnabled and nulled in OnDisabled traps any re-adopt poll that gates on Instance.IsValid(): the entity is never re-driven after a disable.

26.07.08e
"PanelComponent uses OnTreeBuilt, not OnAfterTreeRender"

OnAfterTreeRender(bool) is a Panel hook: on a PanelComponent it fails with CS0115; use parameterless OnTreeBuilt() or OnTreeFirstBuilt().

26.07.22
"SkinnedModelRenderer.SceneObject is null until the renderer goes live, so a spawn-time CastShadows write no-ops"

A SkinnedModelRenderer has no live SceneObject until the renderer first goes live. A Flags.CastShadows write at spawn time lands before the SceneObject exists, so it silently no-ops with no error and no warning. NPCs spawned with a shadow toggle off keep casting shadows anyway. Do not trust the write: read back the state that actually landed and retry on a staggered sweep across the following frames until the read-back matches the value you asked for.

26.07.22
"Static registry persists across editor Play restarts: gate on live objects"

A C# static list/registry survives editor Play stop/start and code hotloads, holding references to destroyed GameObjects: gate iteration on IsValid(), don't rely on clearing alone. It can also mask a new scene's state when stale high-priority entries outrank it. Hand registrations back in OnDestroy.

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