> For the complete documentation index, see [llms.txt](https://studio-docs.sandbox.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://studio-docs.sandbox.game/the-editor/doors-switches-pickups-and-triggers.md).

# Doors, switches, pickups and triggers

Interactable nodes respond when the player is near and presses interact. Trigger zones and pickups respond to **presence** — overlap is enough; no button.

Standard movement templates already include an `ENGINE.InteractionNode` on the pawn. You place the world objects. You do not wire the player.

Search the Place panel or the Inspector **+** list for the display names below (`Door Node`, `Switch Node`, and so on). They are engine **nodes**, not a separate “actor” list.

Default interact input on the built-in player controller is **E** (`KeyE`).

{% hint style="danger" %}
*WARNING: `ENGINE.PickupSpawnerNode` appears in the class list but is not functional (spawn only logs a warning). Do not use it. Place `ENGINE.PickupNode` / `ENGINE.HealthPickupNode` yourself, or ask the agent to scatter them.*
{% endhint %}

## Step 1: Place a door

Add an `ENGINE.DoorNode` (`Door Node`) in the scene, at a doorway height the pawn can reach.

In the Inspector set:

| Property                           | What to set                                                                                                                                             |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `doorType`                         | `hinged` or `sliding` (these are fully implemented). `garage` is basic. `double` currently uses hinged motion. `custom` is for your own animation code. |
| `interactionType`                  | `keypress` to open with **E**. `proximity` opens and closes as the player enters and leaves range — no prompt. `remote` is reserved.                    |
| `startLocked`                      | `true` if the door should start locked                                                                                                                  |
| `proximityRange`                   | How close the player must be (metres)                                                                                                                   |
| `animationDuration`                | Open/close time in seconds                                                                                                                              |
| `maxOpenAngle`                     | Hinged doors, degrees                                                                                                                                   |
| `slideDistance` / `slideDirection` | Sliding doors                                                                                                                                           |

Enter Play mode. With `keypress` and `startLocked` off, walk up and press **E**. The prompt is `Open Door`.

{% hint style="info" %}
*NOTE: Locked doors do not show an interact prompt. `canInteract` is false while locked, so `InteractionNode` hides the prompt on purpose. The door can still report `Locked` from `getInteractionPrompt`, but that string is not shown when interaction is impossible.*
{% endhint %}

## Step 2: Place a switch

Add an `ENGINE.SwitchNode` (`Switch Node`) where the player can stand.

| Property         | What to set                                                                                                                                                 |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `switchType`     | `toggle` — on/off with **E**. `button` — fires every press, no lasting on/off. `proximity` — on while the player is in range, off when they leave (no key). |
| `initialState`   | `off` or `on`                                                                                                                                               |
| `proximityRange` | Detection range                                                                                                                                             |

Play, walk up, press **E** on a toggle or button.

Connecting a switch to a door (unlock, open) is **code**: listen to `onActivated` / `onDeactivated` / `onPressed` on the switch and call the door. The Inspector does not offer a “target door” field. Ask the agent, or see [Project code fundamentals](/best-practices/project-code-fundamentals.md).

## Step 3: Place a health pickup

Add an `ENGINE.HealthPickupNode` (`Health Pickup Node`). It is a `PickupNode` that restores health. Overlap collects it — no **E**.

Set `healAmount` to how much health to restore. Optional: `pickupSoundUrl`, `pickupVolume`, `pickupMaxDistance`.

For a generic collectible, use `ENGINE.PickupNode` (`Pickup Node`) and handle `onPickup` in code.

Play, walk through the pickup. It should collect on overlap.

## Step 4: Place a trigger zone

Add an `ENGINE.TriggerZoneNode` (`Trigger Zone Node`). It is an invisible volume (default box). Scale it to the area you care about.

| Property           | What to set                                                                            |
| ------------------ | -------------------------------------------------------------------------------------- |
| `filter`           | `all`, `playerOnly`, `pawnsOnly`, or `custom` (custom needs a filter function in code) |
| `enableStayEvents` | `true` if you need a repeating “still inside” event                                    |

Events in code: `onActorEntered`, `onActorExited`, `onActorStay` (only if stay events are on).

Play, walk through the volume. Use `playerOnly` so scenery does not fire it.

## Step 5: Play a small loop

1. Door: `interactionType` = `keypress`, `startLocked` = `false`.
2. Health pickup in the same room.
3. Trigger zone in the doorway with `filter` = `playerOnly`.
4. Play, pick up health by walking over it, open the door with **E**.

A locked door plus a pickup that **unlocks** it needs a short script (`onPickup` → unlock). Default characters already handle interact and overlap; you only add that glue.

Custom interactables: extend `ENGINE.ProximityInteractableNode` in TypeScript. Register with `@ENGINE.GameClass()`, then `pnpm build` and **Build Project** (`Ctrl+B` / `Cmd+B`).

## What You've Done

You can place engine doors, switches, pickups, and trigger zones and test them in Play mode. Prompts hide when `canInteract` is false (locked doors). Do not use `PickupSpawnerNode`. Linking a switch or pickup to a door is code, not an Inspector dropdown.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://studio-docs.sandbox.game/the-editor/doors-switches-pickups-and-triggers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
