07 — Puzzle Selection and Drag & Drop
Run Tools → Input System Starter Kit → Create Puzzle Demo (Drag and Drop) in an empty scene. Drag the three colored pieces into the translucent slots — they snap when close, return home when dropped in the void, and Esc aborts a drag mid-air. Tab/E/Q (or shoulder buttons) cycle a highlighted selection without touching the mouse.
Pointer input done right — DragAndDropController.cs
The Puzzle map's Point action is bound to <Mouse>/position, <Pen>/position, and <Touchscreen>/primaryTouch/position. The script reads the action, so it has no idea (and doesn't care) whether the player uses a mouse, stylus, or finger:
Vector2 screen = pointAction.ReadValue<Vector2>();
Vector3 world = worldCamera.ScreenToWorldPoint(screen);
ScreenToWorldPoint is the bridge from screen pixels to world units — with an orthographic camera it's exact; just zero the z.
The drag lifecycle maps onto Click's events:
started(press) →Physics2D.OverlapPointunder the pointer; if it hits aDraggable, grab it and remember the grab offset (so the piece doesn't teleport its center to the cursor — small detail, huge perceived quality).Updatewhile held → glue the piece to the pointer.canceled(release) → find the nearest freeSnapSlotwithin its radius; snap in, orReturnHome().Cancelaction (Esc / B) → abort the drag entirely. Giving "undo the thing I'm doing" its own action is good input design in any genre.
Draggable and SnapSlot are tiny marker components (a home position, an occupancy flag). The controller owns all logic — one place to read, one place to debug.
Selection without a pointer — SelectionCycler.cs
Puzzle games need "change which thing is active": Tab through pieces, shoulder-bump through tools. NextSelection/PreviousSelection handlers move an index and apply purely visual feedback (scale up, full opacity). Note both puzzle scripts call map.Enable() on the same map — that's safe and normal; maps reference-count internally.
This is also your accessibility story: everything the mouse can select, the keyboard can reach.
What about UI drag-and-drop?
This lesson drags world objects. For dragging UI elements (inventory icons in UI Toolkit), the concept transfers but the plumbing differs — UI Toolkit has its own pointer events (PointerDownEvent, PointerMoveEvent, capture). Cross-reference the UI Toolkit Starter Kit; samyam's drag and drop video covers the uGUI flavor.
Exercises
- Merge the two scripts' powers: make Click while a piece is selected via keyboard place the selected piece at the pointer.
- Add a
RotatePieceaction (R / buttonNorth) that rotates the held piece 90° — the start of every tile puzzle. - Require each piece to match a specific slot (give both a
pieceIdint); wrong slots reject the drop. Congratulations: shape sorter → actual puzzle game. - Build check: when all three slots are filled, log "Solved!" — where does that check belong? (Answer: the controller's snap-in moment, not Update.)
Next: 08 - Going Further