Quick answer: Godot 4 RigidBody3D collision_layer set at runtime but other bodies don't see the change? Physics server caches the layer per-shape - call set_deferred or update each shape.

Toggle a switch makes a body ghost-walkable. Other bodies still treat it as solid.

Use set_deferred

body.set_deferred("collision_layer", new_layer)

Defers to end-of-frame. Physics server picks up the change cleanly.

Or set per-shape

If you mutate sub-shapes, update each. Body-level layer is one thing; shape-level layers can differ.

Verify in PhysicsServer dump

Engine's debug overlay shows per-body layer state. Mismatch with your assignment = the propagation didn't happen.

“Physics state has caching. Mutations require deferral.”

For state changes that affect other bodies, set_deferred is the safer default. Direct set is for in-loop physics code only.

Related reading