# Proximity: reacting without a prompt A **Proximity** block (`FMovaIxProximity`) lets an IC fire interactions from an overlap alone, no interaction point, no prompt, no player input at all. A light that turns on as you approach, a fan that spins only while you stand near it, a door that hisses open when you're close: all three are Proximity, not the tagged interaction system on the component itself. ```{image} ../_static/screenshots/shot-editor-viewport-proximity-lamp-mockup.svg :alt: editor viewport proximity lamp (placeholder mockup) :width: 100% ``` Save the real screenshot as: `shot-editor-viewport-proximity-lamp.png` ## Shape: where the volume comes from | `Shape` | What it does | |---|---| | `None` | No auto-volume. Only interactor-driven proximity (if any) applies. | | `Box` | The IC auto-creates a hidden box collision on this actor, sized by `BoxExtent` and placed at `RelativeLocation` / `RelativeRotation`. | | `Sphere` | Same, but a sphere sized by `SphereRadius` (rotation is ignored: a sphere has none). | | `Volume` | Binds to **every** level volume actor tagged `VolumeTag` instead of auto-creating anything: hand-place an irregular trigger in the level and tag it. | `Box` and `Sphere` are the fast path: no separate trigger actor to place, the IC owns the collision itself. `Volume` is for a trigger the two primitives can't express (an L-shape room, a volume that follows a corridor). Only an actor carrying a **`UMovaIxInteractorComponent`** (the player pawn, by convention) triggers a Proximity volume. Static geometry and non-interactor pawns overlap it with no effect. ## Enter / Leave: the same tag grammar `EnterTags` and `LeaveTags` are each a list of ordinary interaction tags, run the moment the interactor enters or leaves range: ```text EnterTags: !On @Lamp LeaveTags: !Off @Lamp ``` These are the same tokens used everywhere else in the plugin (flow prefix, `@`/`%`/`#` target, optional `?` gate), so {doc}`tag-grammar` covers them in full. A Proximity Enter tag can target an external actor (`%Fan^`), gate itself (`?@Power:On`), or fire a Group directly, same as a component tag. ```{mermaid} graph LR A[Player enters volume] -->|EnterTags| B["!On @Lamp"] C[Player leaves volume] -->|LeaveTags| D["!Off @Lamp"] B --> E[Lamp Group: On] D --> F[Lamp Group: Off] ``` ## Use cases | Goal | Shape | Enter | Leave | |---|---|---|---| | Light that turns on as you approach | `Sphere` | `!On @Lamp` | `!Off @Lamp` | | Fan spinning only while you stand near it | `Sphere` | `!Spin @Blade` | `!Stop @Blade` | | Auto-door that opens on approach | `Box` in front of the door | `!Open @Door` | `!Close @Door` | | Ambient trigger tied to a hand-placed volume | `Volume`, `VolumeTag = "AmbientZone"` | `!Play @Speaker` | `!Stop @Speaker` | In the "fan spinning while you stand near it" case, `LeaveTags` firing `!Stop` on exit makes the effect *presence-driven* instead of one-shot: the fan spins only while an interactor sits inside the sphere, with no group left running (and no wasted RampOutTime) once they walk away. ## Proximity vs the player Interactor Proximity and {doc}`../guides/interactor` solve different problems and commonly sit side by side on the same object: - **Proximity** is *passive*: it needs no player input, only presence. Good for ambience and environmental reactions. - The **Interactor** (`UMovaIxInteractorComponent`) is *active*: it finds the best interaction point in view and fires it on a button press. Good for doors, levers, and anything the player should choose to trigger instead of walk into. A single IC can have both: a Proximity sphere that lights a room on approach, and an interaction point on the same mesh that the player presses to do something else entirely. ## See also - {doc}`tag-grammar`: full syntax for the Enter/Leave tag tokens. - {doc}`gates`: gate a Proximity tag with `?` the same way as any other target. - {doc}`../guides/interactor`: the active, aim-and-press counterpart. - {doc}`../guides/debugging`: `mova.ix.Debug` draws the Proximity volume live. - {cpp:class}`FMovaIxProximity`, `EMovaIxProximityShape` in the API reference.