Camera System
The dialogue camera system handles framing during conversations, moving the camera between shot types based on configurable rules and per-beat overrides.
DialogueCameraService orchestrates the camera lifecycle: entering dialogue mode when a conversation starts, applying shots as beats play, and exiting when the conversation ends.
Two camera categories
The system supports two categories of camera behaviour:
FirstPerson
The camera lerps its field of view and rotation toward the target. The player can cancel the look by moving their input. This category is used for subtle framing adjustments that do not take full control away from the player.
Cinematic
The camera uses Cinemachine virtual cameras to frame the shot. Player look input is blocked during cinematic shots. This category is used for dramatic moments where precise framing matters.
Automatic shot selection
When no explicit camera beat is present on a beat group, the system selects a shot automatically using a rule-based ProfileShotSelector.
The selector evaluates a DialogueShotSelectionProfile -- an ordered list of shot selection rules. The first rule that produces a valid shot wins. This means rule order matters: more specific rules should come before general fallbacks.
See Camera Shot Rules for details on the available rules.
Per-beat camera overrides
You can override automatic selection by adding a camera beat to a beat group. A camera beat specifies:
- the shot preset to use
- the transition type (cut, blend)
- an optional duration override
When a camera beat is present, it takes priority over the automatic selection for that beat group.
Shot presets
Presets are divided into three groups.
First-person presets (7)
FP-Focus-- subtle focus on the speakerFP-Inspect-- closer inspection angleFP-Conversation-- relaxed conversational framingFP-Intimidate-- tighter, more intense framingFP-Observe-- wider observational angleFP-Glance-- brief look toward the speakerFP-GroupScan-- pans across a group of participants
Cinematic presets (16)
Cinematic-CloseUp-- tight framing on the speaker's faceCinematic-ExtremeCloseUp-- very tight detail shotCinematic-MediumCloseUp-- head and shouldersCinematic-Medium-- waist-up framingCinematic-OverTheShoulder-- classic over-the-shoulder two-shotCinematic-TwoShot-- both participants visibleCinematic-Wide-- full scene contextCinematic-SideWide-- wide shot from the sideCinematic-PointOfInterest-- framing on a world object rather than a participantCinematic-LowAngle-- camera below eye level looking upCinematic-HighAngle-- camera above looking downCinematic-DutchAngle-- tilted framing for unease or tensionCinematic-Reaction-- framing on the listener's reactionCinematic-Profile-- side-on profile shotCinematic-BirdsEye-- overhead shot
Group presets (4)
GroupWide-- establishes all participants in one frameGroupCluster-- tighter framing of a group clusterGroupOverShoulder-- over-the-shoulder into a groupGroupReaction-- group reaction shot
Group conversations
The camera system supports conversations with two participants with plans to support more. When additional participants are present, the context tracks a GroupCenter (centroid of all participants) and GroupRadius. Group-specific presets and the GroupEstablishingShotRule activate automatically for multi-participant conversations.
Focus points
The camera needs to know where to look. DialogueCameraFocusPoint is a MonoBehaviour you can place on characters to define the camera's look-at target. It supports three modes:
- Auto -- finds a specific bone (default: Head) from a humanoid Animator
- Manual -- an explicit Transform reference you assign
- BakedOffset -- a rotation-aware local-space offset (so it works when the character rotates)
If no focus point component is present, the system auto-detects the head bone on humanoid characters. For non-humanoid agents, the fallback is position + 1.6m up (approximate head height).
The editor Inspector for DialogueCameraFocusPoint includes a "Bake Head Offset From Rig" button that converts the auto-detected bone position into a stable baked offset.
Collision avoidance
The Cinemachine provider includes built-in collision avoidance. Before positioning the camera, it raycasts from the target's focus position toward the ideal camera position. If blocked:
- it rotates the direction by 30-degree increments (left and right alternating)
- it retries up to 6 times (180 degrees total)
- as a final fallback, it uses an elevated side angle to avoid Cinemachine gimbal lock
Speaker and listener colliders are temporarily disabled during collision checks to avoid false hits.
Cinemachine integration
The Cinemachine provider is in a separate assembly (BardTreeLtd.Dialogue.Camera.Cinemachine). It uses a two-vcam ping-pong pool to handle smooth transitions between shots.
Key implementation details:
- the first cinematic shot always uses a Cut transition (avoids blending through characters)
- each vcam gets its own LookAt tracker transform to prevent aim drift during blends
CinemachineBrain.m_DefaultBlendis cached and restored on enter/exitDialogueTransitionTypemaps to Cinemachine blend styles: Cut, EaseInOut, or the configured default
CinemachineDialogueCameraSetup auto-creates the provider and CinemachineBrain at runtime using [RuntimeInitializeOnLoadMethod]. You can also set it up manually via the editor menu at BardTreeLtd/Dialogue/Setup/Setup Scene Camera.
Practical advice
Start with automatic shot selection. It handles most conversations well out of the box. Add explicit camera beats only for dramatic or important moments where specific framing improves the experience.
If shots feel repetitive, adjust the shot selection profile. The repetition avoidance rule exists specifically to prevent the same shot from appearing twice in a row.
Next step
Continue to Camera Shot Rules.