Skip to main content

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 speaker
  • FP-Inspect -- closer inspection angle
  • FP-Conversation -- relaxed conversational framing
  • FP-Intimidate -- tighter, more intense framing
  • FP-Observe -- wider observational angle
  • FP-Glance -- brief look toward the speaker
  • FP-GroupScan -- pans across a group of participants

Cinematic presets (16)

  • Cinematic-CloseUp -- tight framing on the speaker's face
  • Cinematic-ExtremeCloseUp -- very tight detail shot
  • Cinematic-MediumCloseUp -- head and shoulders
  • Cinematic-Medium -- waist-up framing
  • Cinematic-OverTheShoulder -- classic over-the-shoulder two-shot
  • Cinematic-TwoShot -- both participants visible
  • Cinematic-Wide -- full scene context
  • Cinematic-SideWide -- wide shot from the side
  • Cinematic-PointOfInterest -- framing on a world object rather than a participant
  • Cinematic-LowAngle -- camera below eye level looking up
  • Cinematic-HighAngle -- camera above looking down
  • Cinematic-DutchAngle -- tilted framing for unease or tension
  • Cinematic-Reaction -- framing on the listener's reaction
  • Cinematic-Profile -- side-on profile shot
  • Cinematic-BirdsEye -- overhead shot

Group presets (4)

  • GroupWide -- establishes all participants in one frame
  • GroupCluster -- tighter framing of a group cluster
  • GroupOverShoulder -- over-the-shoulder into a group
  • GroupReaction -- 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:

  1. it rotates the direction by 30-degree increments (left and right alternating)
  2. it retries up to 6 times (180 degrees total)
  3. 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_DefaultBlend is cached and restored on enter/exit
  • DialogueTransitionType maps 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.