# Targeting

> Targeting picks the enemy the character fights, locks onto one on a button, switches the lock with a flick, and knows when enemies are near. UPC Targetable makes any actor a candidate.

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

## Set it up (5 minutes)

1. **Make a dummy targetable**

   In a Character Blueprint that stands in as a training dummy, click **Add** and pick **UPC Targetable**. Set its **Aim at Socket** to the skeleton's chest bone, such as `spine_03` on the engine's mannequin. Place the dummy in the level.

   Components panel of **BP_TrainingDummy**:

   - CapsuleComponent (inherited)

     - Mesh (inherited)
   - UPCTargetable (add)

   *A dummy on no team can be picked and locked. A character built on UPC Character Base is targetable already.*
2. **Check the player's targeting and lock button**

   The player's **TargetingComponent**, which UPC Character Base creates, takes its **Targeting Config** from the combat style's **Targeting** fragment, such as the Over Shoulder config `CombatStyle_MyStyle` names ([Combat Styles](https://rigbak.com/docs/universal-player-combat/combat-styles)).

   The lock button is the **UPC Lock On Ability**, which the demo's `AbilitySet_UPC_Default` grants. On your own character:

   1. Create an ability set (right-click in the Content Browser, **UPC > Actions > Ability Set**) named `AbilitySet_MyCharacter`.
   2. On a character built on UPC Character Base, pick it as **Starting Ability Set** in the Class Defaults. A character that keeps its own parent has no such slot: add the set to **Ability Sets to Grant** on its Default Item's **Equippable** fragment ([Character Setup](https://rigbak.com/docs/universal-player-combat/character-setup)).
   3. Add this row ([Input](https://rigbak.com/docs/universal-player-combat/input#abilities-that-answer-a-key)), leaving **Forward Input While Active** off so the second press lets go:

   In **AbilitySet_MyCharacter**, under Granted Gameplay Abilities > Index [ 0 ], set:

   | Property | Value |
   | --- | --- |
   | Ability | UPCLockOnAbility (replaces None) |
   | Input Tag | UPC.Input.LockOn (replaces None) |
   | Input Action | IA_UPC_LockOn (replaces None) |

   A mapping context on the player maps `IA_UPC_LockOn` to a key: the demo controller's `IMC_UPC_Default` maps it to the middle mouse button and the gamepad's top face button. On a controller of your own, add a context that maps it.
3. **Press Play and lock on**

   Put the dummy near the middle of the screen and press the middle mouse button: the camera follows it and the character carries `UPC.State.LockedOn`. Press again to let go.

---

## How a character picks its target

The **Targeting** component finds actors with a switched-on **UPC Targetable** within **Scan Radius**, drops those **Target Teams** leaves out, and ranks the rest with the config's score policies. Each policy rates a candidate from 0 to 1 or vetoes it; a veto or a total of 0 drops the candidate. The best becomes the **current target** (the soft target while nothing is locked), which [Attack Steering](https://rigbak.com/docs/universal-player-combat/attack-steering) reads. A lock press makes its own pick ([Lock on](https://rigbak.com/docs/universal-player-combat/targeting#lock-on)).

A selection pass under the demo's Soulslike soft-target policies: Distance (Weight 2), View Angle (Weight 1) and Line Of Sight (Weight 0, a veto only). Each score is the weighted average of the two scoring policies; D sits behind a wall, so Line Of Sight drops it whatever it would score. The highest score is the target.

| Candidate | Distance | Distance score | Angle off view | View Angle score | Blend |
| --- | --- | --- | --- | --- | --- |
| A | 7.2 m | 0.64 | 8° | 0.91 | 0.73 |
| B | 4.9 m | 0.76 | 35° | 0.61 | 0.71 |
| C | 15.0 m | 0.25 | 2° | 0.98 | 0.49 |
| D | 5.7 m | 0.72 | 26° | 0.71 | vetoed |

*A selection pass under the demo's Soulslike soft-target policies: Distance (Weight 2), View Angle (Weight 1) and Line Of Sight (Weight 0, a veto only). Each score is the weighted average of the two scoring policies; D sits behind a wall, so Line Of Sight drops it whatever it would score. The highest score is the target.*

---

## Make an actor targetable

A lock aims at **Aim at Socket**, a socket or bone, on the first component that has that socket, or on the component tagged **Aim at Component Tag** when that is set. **Aim Offset** moves the point, in centimeters. With neither set it aims at the actor's location.

Untick **Targetable**, or call **Set Targetable**, while the actor is down or out of the fight, and every lock on it lets go. **Release All Locks** lets go of every lock and leaves it targetable, for a phase change or teleport.

---

## The Targeting Config

Duplicate the demo config nearest your fight and tune it. Hand it over through the combat style's **Targeting** fragment, or the Targeting component's **Targeting Config** on a character with no style.

| Config | Picks |
| --- | --- |
| `TargetingConfig_UPC_Freeflow` | The enemy the stick points at, within a dash (8.5 m). No lock-on; engages at 10 m and lets go at 13 m. |
| `TargetingConfig_UPC_OverShoulder` | An enemy within 4 m, ahead of the character and within 45 degrees of where the camera looks (**Measure from Character**: measured from the character along the camera's direction). |
| `TargetingConfig_UPC_Soulslike` | The nearest enemy, favoring the center of the view. |

The two lock configs lock within 20 degrees of the screen's center, let go past 25 m, and switch on `IA_UPC_Flick`. To build one from nothing, right-click in the Content Browser, **UPC > Targeting > Targeting Config**.

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

**Category: Scoring**

| Property | Value |
| --- | --- |
| Score Policies | 3 Array elements |
| Score Policies > Index [0] | Distance |
| Score Policies > Index [0] > Max Distance | 400 |
| Score Policies > Index [0] > Veto Beyond Max Distance | true |
| Score Policies > Index [0] > Weight | 1 |
| Score Policies > Index [1] | Line Of Sight |
| Score Policies > Index [1] > Trace Channel | Visibility |
| Score Policies > Index [1] > Trace from View | false |
| Score Policies > Index [1] > Weight | 0 |
| Score Policies > Index [2] | View Angle |
| Score Policies > Index [2] > Max Angle Degrees | 45 |
| Score Policies > Index [2] > Veto Outside Max Angle | true |
| Score Policies > Index [2] > Measure from Character | true |
| Score Policies > Index [2] > Weight | 1 |
| Lock Score Policies | 2 Array elements |
| Lock Score Policies > Index [0] | View Angle |
| Lock Score Policies > Index [0] > Max Angle Degrees | 20 |
| Lock Score Policies > Index [0] > Veto Outside Max Angle | true |
| Lock Score Policies > Index [0] > Measure from Character | false |
| Lock Score Policies > Index [0] > Weight | 1 |
| Lock Score Policies > Index [1] | Line Of Sight |
| Lock Score Policies > Index [1] > Trace Channel | Visibility |
| Lock Score Policies > Index [1] > Trace from View | true |
| Lock Score Policies > Index [1] > Weight | 1 |

**Category: Lock**

| Property | Value |
| --- | --- |
| Allow Lock | true |
| Lock Break Distance | 2500 |
| Lock Break Grace Seconds | 1.0 |

**Category: Scan**

| Property | Value |
| --- | --- |
| Scan Radius | 2000 |
| Continuous Selection | false |
| Scan Interval | 0.15 (greyed out) |
| Scan Object Types | 2 Array elements |
| Scan Object Types > Index [0] | Pawn |
| Scan Object Types > Index [1] | WorldDynamic |
| Target Teams | Enemies Only |

**Category: Selection**

| Property | Value |
| --- | --- |
| Score Switch Margin | 0.05 |

**Category: Engagement (collapsed until clicked)**

| Property | Value |
| --- | --- |
| Engaged Radius | 0 |
| Engaged Exit Radius | 0 (greyed out) |
| Engaged Linger Seconds | 1.5 (greyed out) |
| Engage Neutrals | false (greyed out) |
| Engaged Tag | UPC.State.Engaged (greyed out) |

**Category: Multiplayer (collapsed until clicked)**

| Property | Value |
| --- | --- |
| Max Reported Target Range | 3000 (advanced) |

**Category: Lock Switch (collapsed until clicked)**

| Property | Value |
| --- | --- |
| Switch Input Action | IA_UPC_Flick |
| Flick Activation Threshold | 0.6 |
| Flick Rearm Threshold | 0.3 |
| Switch Cooldown Seconds | 0.25 |
| Invert Flick X | false |
| Invert Flick Y | false |
| Flick Cone Half Angle Degrees | 60 |
| Max Switch Angle Degrees | 90 |
| Flick Direction Weight | 0.35 |
| Flick Proximity Weight | 0.65 |
| Lock Switch Score Policies | 0 Array elements |

*The demo's Over Shoulder config. Engagement, Multiplayer and Lock Switch open with a click.*

Its **Score Policies** decide who wins (Distance, View Angle, Input Direction and others, each with a **Weight** and an optional veto); see the Advanced drawer "The score policies". These settings shape the scan:

| Setting | Does |
| --- | --- |
| **Scan Radius** | How far the scan looks, in centimeters; 2000 to start. |
| **Scan Object Types** | Collision object types the scan finds; Pawn to start, Pawn and WorldDynamic in the demo. |
| **Continuous Selection**, **Scan Interval** | Re-pick every Scan Interval (0.15 seconds), which a HUD marker following the target needs. Off to start: the component picks only when asked, by a lock press, an attack starting or **Select Target Now**. |
| **Score Switch Margin** | With Continuous Selection on, how much better, 0 to 1, a challenger must score to take the target; 0.05 stops flicker between two near-equal enemies. A pick made on demand ignores it. |
| **Target Teams** | Which teams the character may pick and lock ([Leave teammates out](https://rigbak.com/docs/universal-player-combat/targeting#leave-teammates-out)). |

---

## Lock on

A lock holds one enemy as the target: scoring stops and the character carries `UPC.State.LockedOn`. The **UPC Lock On Ability** locks on one press and lets go on the next; the style decides how the camera follows ([Camera](https://rigbak.com/docs/universal-player-combat/camera#the-camera-while-locked-on)).

A press locks the best candidate under the config's **Lock Score Policies**, or the soft target when that list is empty; a lock cone is a **View Angle** policy with its veto on and a tight angle. The soft target can be the nearer enemy at 40 degrees off the screen's center while a press under a 20-degree cone locks the one at 10 degrees. **Allow Lock** off turns lock-on off.

A lock lets go when its target dies, stops being targetable or joins a team Target Teams leaves out, or stays farther than **Lock Break Distance** (centimeters) for **Lock Break Grace Seconds** (1); the default Lock Break Distance of 0 turns that off.

### Switch the lock with a flick

Set **Switch Input Action** to an Axis2D action (X screen-right, Y screen-up) in a mapping context active while locked, such as the demo's `IA_UPC_Flick`, and a flick moves the lock to the enemy that way. In Blueprint, **Switch Lock Target** switches in a direction of your own, **Pick Flick Target** previews the enemy a flick would reach, **Lock Target** locks an actor, **Clear Lock** lets go, and **Is Locked** and **Get Locked Target** read it.

---

## Leave teammates out

**Target Teams** reads each actor's team from its **UPC Team** component. **Enemies Only**, the default, picks enemies and actors with no team; **No Filter** picks anyone; **Friendlies Only** picks teammates, for a heal; **Neutral Only** picks actors with no team, plus actors on a team you list under the character's UPC Team component's **Exclusions**: excluding team 2 makes team 2 actors count as neutral.

Put the UPC Team component on the pawn. UPC Character Base carries one as **Team Component**: set its **Team Id**. Until then the character is on no team, neutral to all sides, or takes its controller's team when the controller carries one (a UPC Team, or an AI controller's own team).

---

## Know when a fight is on

Set **Engaged Radius** on the config, in centimeters, and the character carries **Engaged Tag** (`UPC.State.Engaged`) while an enemy is that close, for a combat camera, music or a HUD to follow. Only distance and team count, so an enemy behind a wall counts too. Unlike picking, engagement by default counts only an actor on a hostile team, so the character needs a team of its own. Tick **Engage Neutrals** to count actors with no team as well, such as the quick start's dummy. **Engaged Exit Radius**, above Engaged Radius, keeps an enemy pacing on the edge from flipping it; **Engaged Linger Seconds** (1.5) holds the tag after the last enemy leaves.

---

## Read the target from a Blueprint

| Node | Does |
| --- | --- |
| **Get Current Target** | The current target, or none; with Continuous Selection off, the last pick. Call **Select Target Now** first for a fresh one. |
| **Try Get Current Target Point** | True and the aim point while a target exists, for a HUD to read each frame. |
| **On Target Changed**, **On Lock State Changed** | Fire when the target changes, and when a lock is taken, moved or let go. |
| **Is Actor Targetable**, **Resolve Target Point** | Whether any character could target an actor, and where it would aim. |

A transition branches on the target with **Target State** and **Target Distance** ([Action Graph](https://rigbak.com/docs/universal-player-combat/action-graph#branch-on-more-than-the-button)).

---

## Debug it

`UPC.Debug.Targeting 1`, or **Debug Overlay Targeting** on one Targeting component, writes above the character who it fights and each candidate's score or the policy that dropped it. `Log LogUPCTargeting Verbose` logs the same per lock press.

<details>
<summary>Selection in detail (Advanced)</summary>

- **Select Target Now** runs at most one scan and one pick per frame. **Refresh Candidates Now** rescans at once, after a teleport or a wave spawning; **Evaluate Now** picks against the last scan. Neither waits for the once-a-frame limit.
- A held lock, and engagement, rescan on Scan Interval with Continuous Selection off, so a flick sees enemies that came into range after the lock; engagement can end up to one Scan Interval late.
- Keep a Distance policy's Max Distance without a veto at or above Scan Radius, so every scanned candidate keeps a usable rating.
- Input Direction's resting rating of 1 still counts its Weight, softening the other policies' differences; lower its Weight to let them decide the resting pick.
- **Lock Target** refuses the character itself, an untargetable actor, one Target Teams leaves out, and any lock with no config or Allow Lock off. Locking another actor while locked moves the lock.
- **Share Lock With Teammates** tells teammates which enemy this character locks, through their own components' **On Teammate Lock Changed** and **Get Teammate Locks**, for a marker you draw.
- **Build Targeting Context** is what a pick judges against: the character's location, eyes, camera view and last movement input. Override it in a child class of the Targeting component to aim from somewhere else, such as an aim-assist reticle.

</details>

<details>
<summary>The score policies (Advanced)</summary>

A candidate scores the average of its policies' ratings, each counted by its **Weight**; a policy at Weight 0 only vetoes, a pure filter. A tie goes to the nearer candidate, and with no policies the nearest wins.

| Policy | Rates a candidate |
| --- | --- |
| **Distance** | Higher the closer, 0 at **Max Distance** (2000 cm). **Veto Beyond Max Distance** drops anything farther, so an attack aimed past it plays in place. |
| **View Angle** | Higher the nearer the view's center, 0 at **Max Angle Degrees** (90). **Veto Outside Max Angle** makes a hard cone; **Measure from Character** measures from the character along the camera's direction, leaving out an enemy behind its back. |
| **Input Direction** | Higher the nearer the stick's push, 0 at Max Angle Degrees (90); all rate 1 while the stick rests. With its veto, only an enemy in the pushed direction counts. |
| **Aim Direction** | Higher the nearer the aim (the stick when pushed, else the camera), 0 at Max Angle Degrees (45). Its veto starts on, so aiming at empty space picks no one. |
| **Line Of Sight** | Drops a candidate something blocks on **Trace Channel** (Visibility); Weight 0 to start. **Trace from View** traces from the camera, not the character's eyes. |

In the demo, Freeflow rates Distance, Input Direction (Weight 2) and Line Of Sight; Over Shoulder rates Distance, Line Of Sight and View Angle measured from the character, each with its veto; Soulslike rates Distance (Weight 2), View Angle and Line Of Sight. The lock configs lock with View Angle and a Line Of Sight traced from the camera.

</details>

<details>
<summary>Flick tuning (Advanced)</summary>

| Setting | Does |
| --- | --- |
| **Flick Activation Threshold** | How far, 0 to 1, the stick must be pushed to switch; 0.6 ignores drift. |
| **Flick Rearm Threshold** | How far it must come back before the next flick counts; 0.3, so a stick held over switches once. |
| **Switch Cooldown Seconds** | The shortest gap between two switches; 0.25. |
| **Invert Flick X**, **Invert Flick Y** | Flip a direction for an action that runs the other way, such as inverted pitch. |
| **Flick Cone Half Angle Degrees** | How far off the flick an enemy may sit and still be picked; 60. |
| **Max Switch Angle Degrees** | How far across the screen from the current lock one flick may throw it; 90. |
| **Flick Direction Weight**, **Flick Proximity Weight** | Matching the flick's direction (0.35) against stepping to the enemy nearest the current lock on screen (0.65). |
| **Lock Switch Score Policies** | Extra policies for a switch only, such as a Line Of Sight veto. |

</details>

<details>
<summary>A score policy of your own (Advanced)</summary>

Create a Blueprint class whose parent is `UPCTargetScorePolicy` and override **Score Candidate**, returning 0 to 1, and **Is Candidate Valid**, returning false to veto. Both receive the **Context** (the character, where it stands and looks, the stick's direction) and the **Candidate** (the actor and its aim point). One policy object serves every character using the config, so read only the two inputs and keep no variables on the policy.

</details>

<details>
<summary>Targeting in multiplayer (Multiplayer)</summary>

- Picking runs where the inputs live: on a player's own machine for a player, on the server for an AI. Other machines hold no targeting state for the character.
- A player's machine tells the server its target and lock whenever either changes, so a transition condition or paired action on the server names the same enemy and holds the same lock. An attack carries its own target.
- The server ignores a reported target beyond the config's **Max Reported Target Range** (3000 cm, under Multiplayer's advanced settings; 0 turns it off), or one the character may not target.
- `UPC.State.LockedOn` sits on the player's machine and the server, each adding it from its own lock; `UPC.State.Engaged` only on the machine that picks the targets.
- **Targetable** replicates: switch it on the server and every machine lets go of its lock.
- The config does not replicate; set it on every machine, as a style's Targeting fragment on Every Machine does.
- A controller does not reach other players' machines, so a character teamed only through its controller reads as teamless there; keep the UPC Team component on the pawn.
- **Share Lock With Teammates** sends the server's lock to every machine showing the character; each machine hands it only to its own players on that team.

</details>

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

- `UUPCTargetingComponent` holds selection and lock; `BuildTargetingContext` is a `BlueprintNativeEvent` returning `FUPCTargetingContext`.
- A score policy subclasses `UUPCTargetScorePolicy` and overrides `ScoreCandidate_Implementation` and `IsCandidateValid_Implementation(const FUPCTargetingContext&, const FUPCTargetCandidate&)`.
- `UUPCTargetingComponent::ReleaseLocksOnActor(AActor*)` makes every character locked onto an actor let go, for an actor with no Targetable component.
- `UUPCLockOnAbility::FallbackCamera` is the `UUPCStyleFragment_Camera` the lock follows with when the style carries none.

</details>

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

| Symptom | Cause |
| --- | --- |
| The character picks nothing. | No config (a warning names it), no switched-on UPC Targetable, an object type outside Scan Object Types, or Target Teams leaves it out. |
| A lock press finds nothing. | **Allow Lock** is off, or the lock policies veto everything: an enemy outside the lock cone or behind cover. |
| The target flickers between two enemies. | Raise Score Switch Margin. |
| A HUD marker trails its enemy. | Tick Continuous Selection. |

Validating a config warns on a Lock Break Distance below Scan Radius or an Engaged Exit Radius below Engaged Radius, and fails engagement with no Engaged Tag, no Scan Object Types, or a radius beyond Scan Radius.

</details>

---

Previous page: [Combat Styles](https://rigbak.com/docs/universal-player-combat/combat-styles). Next page: [Attack Steering](https://rigbak.com/docs/universal-player-combat/attack-steering)
