"A component that reads Input in OnUpdate fires on every instance at once"
▸ SYMPTOM
You put an input read inside a per-entity component. The component calls Input.Pressed or Input.Down in its own OnUpdate to trigger an action. With one entity on screen it works exactly as intended.
Add more instances of the same component and one keypress fires the action on every instance at once. In a multi-vehicle arena, a single press to repair and respawn teleports the whole field back to its spawn points. Nothing in the log points at input, so it reads as a free world reset, not an input bug.
▸ CAUSE
Input.Pressed and Input.Down read a global input state. They do not carry a per-entity target. A component that reads them in OnUpdate samples that one global state once per instance, every frame.
The live case gated the read only on IsProxy. IsProxy is a network-replication check. It answers whether the entity is replicated from elsewhere, not whether this instance should respond to a keypress. In single-player or local testing with one entity, IsProxy is false and the read is correct. In a multi-entity arena with several locally-simulated instances, none of them is a proxy. So every instance passes the same gate and responds to the same press.
▸ FIX
Gate any global input read inside a per-entity component on genuine local ownership, not on proxy status.
- Read input only on the actively-controlled entity. Confirm this instance is the one the local player drives before you read
Input.PressedorInput.Down. A design that hands control to one entity at a time reads input on that entity only. - Do not treat
IsProxyas an ownership test.IsProxyfalse means simulated here, which can be true for many entities at once. It does not mean the player controls this one. - Audit every unconditional
Input.*read when the entity count can exceed one. A per-entity component with an unguarded input read is safe only while exactly one instance of it exists.
▸ WHY IT WORKS
The bug is a scope mismatch: a global input state read from a per-entity scope. Ownership is the missing scope. When the read runs only on the entity the local player controls, the global state maps to exactly one responder, whatever the instance count. IsProxy cannot supply that scope, because replication status and control ownership are different questions. One keypress crossing many non-proxy instances is exactly where they diverge.
- Published