All work

Scene & Camera

The main camera never free-looks. It snaps between fixed positions, one per view, with smooth tweens, and locks while a view is settled. That's what produces the 2.5D, pseudo-3D look. Each view is defined by a placed GameObject in the scene, a view anchor whose transform marks exactly where the camera should sit, so re-framing a shot is just dragging an object in the editor.

View anchors

Each view, Desk, Tabletop, Computer, is a SceneViewAnchor placed in the scene at the desired camera transform, identified by a SceneViewKey enum, optionally overriding FOV or ortho size and holding a reference to that view's UI root. Tweaking a view's framing means dragging the anchor; adding a view, a scanner-intake shot, a submission chute, means dropping in a new anchor and a new key.

Two cooperating components

Responsibility is split cleanly. SceneViewStateMachine, a scene singleton, decides when to transition and fires OnViewChanged, OnTransitionStarted, and OnTransitionCompleted events, but never lerps the camera. SceneCameraController lives on the camera and executes the lerp toward a target anchor over a configurable duration and easing curve, but never decides when. A transition config supplies the timing, around 0.4 seconds with an ease-out by default.

Input gating and nested logic

While a transition is in flight, view-specific input is suppressed: each view's canvas toggles its CanvasGroup interactable and blocksRaycasts flags on the transition boundaries. Views can run their own internal state machines independent of the scene system: the computer view's machine listens for OnViewChanged and resets itself to idle on entry, shutting down cleanly on exit.