# Camera

> UPC Camera Rig gives the player a third-person camera: the combat style or weapon in hand sets its distance and view, a tag such as sprinting blends in a change, and it follows a locked target.

Markdown version of https://rigbak.com/docs/universal-player-combat/camera, a page of the Universal Player Combat documentation. Link that page when citing it.

## Set it up (5 minutes)

1. **Add the rig to the character**

   The demo character `BP_UPC_Character` has the rig; skip to step 2. On your own character ([Character Setup](https://rigbak.com/docs/universal-player-combat/character-setup)), finish the [Sprint and Speed](https://rigbak.com/docs/universal-player-combat/sprint-and-speed) quick start first, since step 3 reads `UPC.State.Sprinting`. Click **Add** and pick **UPC Camera Rig**. It takes the character's one camera and its spring arm, or builds both when play starts on a character with none. With several cameras it binds none: call **Bind Rig** ([Choosing one camera of several](https://rigbak.com/docs/universal-player-combat/camera#debug-it)).

   Components panel of **BP_MyCharacter**:

   - SpringArm (inherited)

     - TPSCamera (inherited)
   - UPCCameraRig (add)

   *UPC Character Base does not add the rig.*

   A spring arm pulls the camera in when a capsule or mesh blocks the **Camera** channel, so an enemy walking between camera and player snaps the view onto the player's back. UPC Character Base ignores that channel (**Ignore Camera Collision**, on by default); on any other character, enemies included, set the capsule's and mesh's **Camera** response to **Ignore**.
2. **Give the combat style a Camera Rig fragment**

   In the Combat component's **Style** ([Combat Styles](https://rigbak.com/docs/universal-player-combat/combat-styles)), add a **Camera Rig** fragment. Its **Settings** are the style's camera: 350 cm back, 90 degree view.
3. **Add a camera state for sprinting**

   In the fragment's **States**, add a row: **Label** `Sprinting`, **Required Tags** `UPC.State.Sprinting`. Tick **Arm Length** (`80`, Mode **Add**) and **Field Of View** (`1.1`, Mode **Scale**).

   In **CombatStyle_MyStyle**, under States, set:

   | Property | Value |
   | --- | --- |
   | Label | Sprinting |
   | Required Tags | UPC.State.Sprinting |
   | Arm Length | 80 (replaces 350) |
   | Arm Length Mode | Add (replaces Replace) |
   | Field Of View | 1.1 (replaces 90) |
   | Field Of View Mode | Scale (replaces Replace) |

   *While the character sprints, the camera sits 80 cm further back and sees a tenth wider.*
4. **Press Play and sprint**

   Hold sprint while moving: the camera eases back and widens over half a second.

---

## How the rig builds the view

What the player sees, top first. Each layer works over the ones below it.

1. **Camera states** (the style's States rows): Stack by Priority, the higher on top. Each changes only the values it ticks, as far as it has blended in.
2. **Base settings** (the weapon in hand, the combat style or the rig's Default Settings): The first of the three that has one supplies the whole set.

Arm Length, Socket Offset and the lag speeds go onto the spring arm; Field Of View and Camera Tilt go onto the view itself, so the player's aim never moves. A shoulder swap, Blueprint layers, requested views and shots sit above these; each has its section below.

---

## Set the camera's distance and framing

The base is one whole set: the **Camera Rig** fragment on the weapon in hand, else the style's, else the rig's **Default Settings**. A weapon fragment that changes only Arm Length still brings its own Field Of View. Put it on the item definition or its [item preset](https://rigbak.com/docs/universal-player-combat/items#share-fragments-with-a-preset); only the item that gives the character its moves counts ([Equipment](https://rigbak.com/docs/universal-player-combat/equipment#which-item-gives-the-moves)). On a change, distance, offset, tilt and field of view ease over; lag speeds and follow settings switch at once.

**Details panel: UPCCameraRig** (component, in BP_MyCharacter)

**Category: Camera**

| Property | Value |
| --- | --- |
| Output Mode | Automatic |
| Create Rig if Missing | true |

**Category: Camera > Default Settings**

| Property | Value |
| --- | --- |
| Field Of View | 90 |
| Arm Length | 350 |
| Socket Offset | (0, 40, 60) |
| Camera Tilt | 0 |
| Position Lag Speed | 10 |
| Rotation Lag Speed | 0 |
| Settings Blend Speed | 8 |
| Follow Soft Target | false |
| Soft Follow Speed | 3 (greyed out) |
| Soft Follow Deadzone | 8 (greyed out) |
| Soft Follow Resume Delay | 0.75 (greyed out) |

**Category: Shoulder**

| Property | Value |
| --- | --- |
| Shoulder Swap Seconds | 0.35 |

*Default Settings is the camera a character gets when neither its combat style nor the weapon in hand brings one.*

| Setting | Does |
| --- | --- |
| **Field Of View** | Horizontal view in degrees, 5 to 170; 90 to start. |
| **Arm Length** | Distance behind the spring arm's pivot, in centimeters; 350 to start. Needs a spring arm. |
| **Socket Offset** | Moves the camera from the arm's end: Y over a shoulder (40), Z up (60). |
| **Camera Tilt** | Tilts the view from the aim, -45 to 45 degrees, negative looking down; a raised camera needs a downward tilt. The aim stays put. |
| **Position Lag Speed**, **Rotation Lag Speed** | How fast the arm catches up with movement (10) and turning (0); 0 turns that lag off. |
| **Settings Blend Speed** | How fast a change of settings settles; 8, and 0 applies at once. |

> **Warning**
>
> The rig writes Arm Length, Socket Offset and both lag speeds onto the spring arm every frame, and Field Of View onto the view. Edit them on the rig's settings, not on the arm or camera.

---

## Change the camera while a tag is on

A row in the style's Camera Rig **States** applies while the character carries all its **Required Tags** (a parent tag met by any child; empty always met) and none of its **Blocked Tags**. It changes only ticked values and blends on its own clock.

**Details panel: CombatStyle_MyStyle** (data asset, in Content Browser)

**Category: Style**

| Property | Value |
| --- | --- |
| Fragments | 1 Array element |
| Fragments > Index [0] | Camera Rig |
| Fragments > Index [0] > Settings > Field Of View | 90 (folded until clicked) |
| Fragments > Index [0] > Settings > Arm Length | 350 (folded until clicked) |
| Fragments > Index [0] > Settings > Socket Offset | (0, 40, 60) (folded until clicked) |
| Fragments > Index [0] > Settings > Camera Tilt | 0 (folded until clicked) |
| Fragments > Index [0] > Settings > Position Lag Speed | 10 (folded until clicked) |
| Fragments > Index [0] > Settings > Rotation Lag Speed | 0 (folded until clicked) |
| Fragments > Index [0] > Settings > Settings Blend Speed | 8 (folded until clicked) |
| Fragments > Index [0] > Settings > Follow Soft Target | false (folded until clicked) |
| Fragments > Index [0] > Settings > Soft Follow Speed | 3 (folded until clicked, greyed out) |
| Fragments > Index [0] > Settings > Soft Follow Deadzone | 8 (folded until clicked, greyed out) |
| Fragments > Index [0] > Settings > Soft Follow Resume Delay | 0.75 (folded until clicked, greyed out) |
| Fragments > Index [0] > States | 2 Array elements |
| Fragments > Index [0] > States > Sprinting > Label | Sprinting |
| Fragments > Index [0] > States > Sprinting > Required Tags | UPC.State.Sprinting |
| Fragments > Index [0] > States > Sprinting > Blocked Tags | no tags |
| Fragments > Index [0] > States > Sprinting > Priority | 0 |
| Fragments > Index [0] > States > Sprinting > Blend in Seconds | 0.50 |
| Fragments > Index [0] > States > Sprinting > Blend Out Seconds | 0.75 |
| Fragments > Index [0] > States > Sprinting > Blend Option | Hermite-Cubic InOut |
| Fragments > Index [0] > States > Sprinting > Arm Length | 80 (override ticked) |
| Fragments > Index [0] > States > Sprinting > Arm Length Mode | Add |
| Fragments > Index [0] > States > Sprinting > Socket Offset | (0, 40, 60) (override unticked) |
| Fragments > Index [0] > States > Sprinting > Camera Tilt | 0 (override unticked) |
| Fragments > Index [0] > States > Sprinting > Field Of View | 1.1 (override ticked) |
| Fragments > Index [0] > States > Sprinting > Field Of View Mode | Scale |
| Fragments > Index [0] > States > Engaged > Label | Engaged |
| Fragments > Index [0] > States > Engaged > Required Tags | UPC.State.Engaged |
| Fragments > Index [0] > States > Engaged > Blocked Tags | no tags |
| Fragments > Index [0] > States > Engaged > Priority | 1 |
| Fragments > Index [0] > States > Engaged > Blend in Seconds | 0.50 |
| Fragments > Index [0] > States > Engaged > Blend Out Seconds | 0.75 |
| Fragments > Index [0] > States > Engaged > Blend Option | Hermite-Cubic InOut |
| Fragments > Index [0] > States > Engaged > Arm Length | 400 (override ticked) |
| Fragments > Index [0] > States > Engaged > Arm Length Mode | Replace |
| Fragments > Index [0] > States > Engaged > Socket Offset | (0, 40, 120) (override ticked) |
| Fragments > Index [0] > States > Engaged > Socket Offset Mode | Replace |
| Fragments > Index [0] > States > Engaged > Camera Tilt | -15 (override ticked) |
| Fragments > Index [0] > States > Engaged > Camera Tilt Mode | Replace |
| Fragments > Index [0] > States > Engaged > Field Of View | 90 (override unticked) |

*The Sprinting row from the quick start, and an Engaged row at Priority 1 that pulls the camera back to 400 cm, raises it and tilts it down while enemies are near. An unticked value keeps whatever the layers below give. The panel shows the Camera Rig fragment alone; the style's other fragments stay beside it.*

| Setting | Does |
| --- | --- |
| **Priority** | A higher row goes on top and works on the result of the rows below; on a tie, a row lower in the list goes on top. |
| **Blend in Seconds**, **Blend Out Seconds** | Time to take over (0.5) and hand back (0.75); 0 cuts. |
| **Blend Option** | The easing, **Hermite-Cubic InOut** to start; **Custom** reads **Custom Blend Curve**. |
| **Arm Length**, **Socket Offset**, **Camera Tilt**, **Field Of View** | Tick one to change it. Mode **Replace** sets the value, **Add** adds to the layers below, **Scale** multiplies them (a Field Of View of 0.9 narrows the view to 90 percent). |

Two rows, Sprinting and Engaged (Priority 1, Arm Length 400 Replace), over a base Arm Length of 350 and Field Of View of 90:

| The character is | Arm Length | Field Of View |
| --- | --- | --- |
| Sprinting | 350 + 80 = 430 | 90 × 1.1 = 99 |
| Engaged | 400 (Replace) | 90 (unticked on Engaged) |
| Sprinting and engaged | 400: Engaged sits on top and replaces the 430 below it | 99: only Sprinting changes it |

Any tag drives a row: `UPC.State.Sprinting` at sprint pace, `UPC.State.Engaged` while enemies are near (**Engaged Radius**, and **Engage Neutrals** for a team-less dummy: [Targeting](https://rigbak.com/docs/universal-player-combat/targeting#know-when-a-fight-is-on)), `UPC.State.LockedOn` while locked, or your own through **Add Loose Gameplay Tags**.

<details>
<summary>No combat style? Push the change from Blueprint (Alternative)</summary>

**Begin Camera Layer** adds the same change with no tag and no style, until you pass its handle to **End Camera Layer**, which blends it out. Give it a **Source** (such as self) and a camera layer (a state row's Priority, blends and ticked values, without tags).

Blueprint graph, nodes in reading order:

- **Comment box: When the moment starts**

  - **UPCCameraRig** (variable)
  - **Sprint Layer** (variable)
  - **Begin Camera Layer** (function; Target is UPCCamera Rig Component); inputs: Target, Source = self, Layer; outputs: Return Value
  - **Sprint Layer Handle** (set variable)
- **Comment box: When the moment ends**

  - **UPCCameraRig** (variable)
  - **Sprint Layer Handle** (variable)
  - **End Camera Layer** (function; Target is UPCCamera Rig Component); inputs: Target, Handle

A pushed layer stacks with the style's states by Priority, above a state of equal Priority; a newer one sits above an older one. Destroying the Source ends its layer. The rig warns and refuses a layer with no Source or an unusable value, and every layer while switched off.

</details>

---

## Swap the camera to the other shoulder

**Swap Shoulder** slides the camera to the other shoulder in **Shoulder Swap Seconds** (0.35; 0 cuts); a second call brings it back. It mirrors the sideways part of every Socket Offset (a centered camera stays put) on top of the states. **Set Shoulder Mirrored** picks a side; **Is Shoulder Mirrored** reads it.

---

## Follow the soft target

Tick **Follow Soft Target** and, while nothing is locked, the camera turns toward the [soft target](https://rigbak.com/docs/universal-player-combat/targeting) at **Soft Follow Speed** (3; 0 turns it off). It leaves the view alone inside **Soft Follow Deadzone** (8 degrees) and waits **Soft Follow Resume Delay** (0.75 s) after the player turns the camera. Tick the Targeting Config's **Continuous Selection** so a target stays picked as the player moves.

---

## The camera while locked on

While a lock is held, the style's lock camera fragment turns the camera: **Camera, Lock Follow** aims at the target, **Camera, Frame Both** between character and target, keeping both in frame. A style with neither uses the lock-on ability's **Fallback Camera** (a Lock Follow at defaults; None turns the follow off). [Targeting](https://rigbak.com/docs/universal-player-combat/targeting#lock-on) covers locking on.

**Details panel: Camera, Lock Follow** (instanced object, in CombatStyle_MyStyle)

**Category: Style**

| Property | Value |
| --- | --- |
| Fragments | 1 Array element |
| Fragments > Index [0] | Camera, Lock Follow |
| Fragments > Index [0] > Rotation Interp Speed | 10 |
| Fragments > Index [0] > Interp Speed by Angle | None |
| Fragments > Index [0] > Min Pitch | -55 |
| Fragments > Index [0] > Max Pitch | 35 |
| Fragments > Index [0] > Deadzone Angle Degrees | 0 |
| Fragments > Index [0] > Stabilize Close Range | true |
| Fragments > Index [0] > Close Range Full Strength Distance | 150 |
| Fragments > Index [0] > Close Range Fade End Distance | 450 |
| Fragments > Index [0] > Close Range Min Pitch | -20 |

*Camera, Frame Both carries the same fields plus Framing Bias (0.5, halfway between the character and the target) and Aim Height Offset (0 cm). The panel shows this fragment alone; the style's other fragments stay beside it.*

| Setting | Does |
| --- | --- |
| **Rotation Interp Speed**, **Interp Speed by Angle** | Turn speed toward the lock; 8 to 14 reads as a firm souls-like follow, 0 stops the turn. The curve, when set, reads how far off the target the camera is. |
| **Min Pitch**, **Max Pitch** | How far down and up the camera may point while locked; equal values hold one pitch. |
| **Deadzone Angle Degrees** | An angle around the target inside which the follow stops turning; 0 corrects all the time. |
| **Stabilize Close Range** | Steadies the camera as the target comes close: full strength at 150 cm, faded by 450 cm, pitch held no lower than -20 degrees. |

<details>
<summary>A lock-on camera of your own (Advanced)</summary>

Make a Blueprint child of the Camera, Lock Follow fragment and override **Compute Locked View Rotation**. It receives the character, the camera's rotation and location, the look-at point and **Delta Time**, and returns where the camera points (return the current rotation to leave it where the player put it). Add it to the style in place of the built-in fragment.

</details>

---

## Take over the view for a moment

**Begin Camera Override** shows a world-space view in place of the gameplay camera and returns a handle; the view holds until you pass it to **End Camera Override**. **Play Camera Shot** plays a **Camera Shot** asset (**UPC > Presentation > Camera Shot**) of camera keys, ending at its last key or earlier through End Camera Override. Both blend in and out and sit above everything else: the highest Priority wins (the newest on a tie).

<details>
<summary>Requests and shots in detail (Advanced)</summary>

| Node | Does |
| --- | --- |
| **Begin Camera Override** | Shows a location, rotation and field of view, at Priority 0 with blends of 0.25 seconds. |
| **Update Camera Override** | Moves a requested view without restarting its blend; a Camera Shot cannot move. |
| **End Camera Override** | Blends to the next request or the gameplay camera. |
| **Play Camera Shot** | Plays a shot on the game clock, placed by **Reference Transform**, an offset from **Reference Actor** when set. Priority 100, blends of 0.35 seconds, **Play Rate** 1. |
| **Has Camera Override** | True while a request or its blend back holds the view. |

- A request does no collision check, so a view inside a wall shows the wall. Destroying its **Source** ends it.
- A shot's keys each hold a time in seconds, a location and rotation relative to the shot's reference, a field of view, and **Linear**, **Smooth** (default) or **Hold** to the next key. The first key sits at 0, times rise, and the last key's time is the shot's length; **Use Tangents** curves the path through a key.

</details>

### Cameras for paired actions

Three hooks on a paired action's role change that player's camera (the character needs the rig). Add them to the role's **Hooks** in the [Pairing Editor](https://rigbak.com/docs/universal-player-combat/pairing-editor), which also keys a shot.

| Hook | Does |
| --- | --- |
| **Auto Cinematic View** | Frames this role and a partner from an angle around the action's anchor (the ground point it is placed on), sweeping for walls, then blends back when the role ends. |
| **Authored Camera Shot** | Plays a Camera Shot on the action's own clock from **Start Time Seconds**. |
| **Camera Layer** | Pushes a camera layer while the role runs, such as a zoom. |

<details>
<summary>Paired camera hook settings (Advanced)</summary>

- **Auto Cinematic View**: **Focus Role** (None picks the nearest active participant), **Framing Margin** (1.2), **Height Offset** (50 cm), **View Angle** (90; 0 is in front of the anchor, 90 to its right, 180 behind) and **Choose Nearest Side**. Advanced: Field Of View 60, Minimum Distance 250 cm, Follow Speed 5, Probe Radius 12 cm, blends of 0.35 seconds, Priority 100.
- **Authored Camera Shot**: **Shot** and **Start Time Seconds**. Advanced: **Reference Role** (None places the keys on the action's anchor), **Look at Role**, **Look At Offset**, blends and Priority 100.
- **Camera Layer**: the values a camera state ticks, at Priority 20 with blends of 0.15 and 0.4 seconds.

</details>

---

## Debug it

`Log LogUPCCamera Verbose` raises the camera's log. **Get Resolved Settings** returns the settings the camera is at now, every layer and the shoulder side included.

<details>
<summary>Choosing one camera of several (Advanced)</summary>

Call **Bind Rig** with the camera and the spring arm it hangs from (an ancestor of the camera on the same character); with no arm, the rig tunes no distance, offset or lag. The choice survives switching the rig off and on, an output change and repossession; pass no camera to clear it. Bind Rig does not activate the camera: the engine shows the first active camera, so activate yours (binding an inactive one warns). **Create Rig if Missing** off stops the rig building its own arm and camera.

</details>

<details>
<summary>What the rig touches (Advanced)</summary>

- On the spring arm the rig writes Target Arm Length, Socket Offset, Camera Lag Speed and Camera Rotation Lag Speed (turning position and rotation lag on or off with them) and leaves the rest. Switching the rig off puts those back on an arm it did not build and destroys an arm and camera it built.
- Field Of View and Camera Tilt go onto the view through the player's camera manager, so the camera component's own Field Of View does nothing while the rig runs; camera shakes still apply on top.
- The soft follow never aims lower than 55 degrees down or higher than 35 up, ignores a target behind the view, and pauses while a request holds the screen. **Notify Look Input** starts its pause for a look input that does not turn the controller.
- A shoulder swap never mirrors a request, and neither the soft follow nor the lock-on camera turns the controller while one holds the view.

</details>

<details>
<summary>Driving your own camera system (Advanced)</summary>

When another system owns the camera (your own camera manager, Gameplay Cameras), set **Output Mode** to **External** (or call **Set Output Mode**). The rig then builds no camera, writes nothing on a spring arm, never turns the controller and runs no soft follow. Your system calls **Evaluate Camera View** each update with its view and the elapsed seconds and uses the location, rotation and field of view it returns (including every state's, layer's and request's tilt and field of view), and reads **Get Resolved Settings** for distance, offset and lag. The lock-on ability turns the controller toward a locked target itself.

</details>

<details>
<summary>The demo</summary>

- `BP_UPC_Character` carries a SpringArm, a TPSCamera and the rig, and calls Swap Shoulder from `IA_UPC_SwapCamera`.
- Over Shoulder carries a close camera over the shoulder. Freeflow carries two rows: `Engaged` pulls the camera back while enemies are near, and `Sprinting` while it runs.

</details>

<details>
<summary>What runs where (Multiplayer)</summary>

- The camera is local: the rig runs only on the controlling player's machine, and states, layers, requests, shots and shoulder side replicate nothing. A dedicated server refuses every request, layer and shot, and Evaluate Camera View returns the view it was given.
- A state reads the tags on the player's own machine (`UPC.State.Sprinting` also sits on the server). A loose tag added only on the server never reaches the camera; add it with **Should Replicate** ticked, or through a gameplay effect on an ability system replicating in Mixed or Full mode.
- A possession change drops every request and pushed layer, except at the pawn's first possession, which keeps anything pushed before the controller arrived. The shoulder side stays.
- The paired action camera hooks act only for the local player in their role, read the action's record every machine holds, and send nothing.

</details>

<details>
<summary>C++</summary>

- `UUPCCameraRigComponent::EvaluateCameraView(const FUPCCameraView& BaseView, float DeltaSeconds)` is the entry for an External integration; `GetResolvedSettings()` returns an `FUPCCameraRigSettings`.
- The lock-on ability asks the pawn for an `IUPCCameraControlProvider` (found with `FindComponentByInterface`) and leaves the controller alone while `OwnsCameraFollow()` answers true. A camera component of your own implements it to take the lock follow over; the interface is C++ only. The rig answers true while it runs in Automatic output for the local player, and while a request holds the view in External output.
- `UUPCStyleFragment_Camera::ResolveForLock(const AActor* Character)` answers which camera fragment turns the view: the style's, else the lock-on ability's `FallbackCamera`, else the class default. A subclass overrides `ComputeLockedViewRotation_Implementation` and can call the protected `FollowStep` for the built-in follow math.
- A paired view hook of your own subclasses `UUPCPairedActionHook_CameraView` and implements `BuildView(float DeltaSeconds, FUPCCameraView& OutView)`, answering Show, Wait or End each frame; the base owns the request, its Priority and its blends.

</details>

<details>
<summary>Troubleshooting (Advanced)</summary>

| Warning says | Fix |
| --- | --- |
| Camera Rig on ... could not discover one camera | Several cameras: pick one with **Bind Rig**. None and no root component: give the character a root. |
| Camera Rig on ... has invalid camera settings | A value in the weapon's, style's or rig's settings is outside the ranges above; built-in defaults apply. |
| Begin Camera Layer on ... was refused | The layer has no Source or an unusable value. |
| Begin Camera Override on ... refused | The Source is gone, the view is not finite, its field of view is outside 5 to 170, or a blend time is not a number. |
| Play Camera Shot on ... requires a shot with valid keys... | Fewer than two keys, a first key not at 0, key times not rising, a field of view outside 5 to 170, a Play Rate of 0 or less, a Reference Transform that is not finite, or a Reference Actor in another world. |

Validating the Combat Style fails Camera Rig settings or a row holding a value the camera cannot use, and a row whose Required and Blocked Tags share a tag. A row with no tags, no ticked value, or a Custom blend with no curve warns.

</details>

---

Previous page: [Attack Steering](https://rigbak.com/docs/universal-player-combat/attack-steering). Next page: [Sprint and Speed](https://rigbak.com/docs/universal-player-combat/sprint-and-speed)
