Skip to content

Targeting

All · 15 min read · No code

Target mode is a gameplay ability, Battle/Targeting/GA_XenoCore_TargetMode, built on the C++ class UXenoCoreGameplayAbility_TargetMode. While it is active it holds the selected enemy, shows the battle HUD (diamond over the target, target badge, player plate, arts palette), and drives the battle facing. There is no targeting component. The one idea: the lock and its target are one object. The ability is instanced once per pawn, so when the ability ends the target is gone, and anything that wants "what am I fighting?" asks the ability through one function, Get Current Target.

At a glance

In play: RB (Tab) locks on to the enemy nearest the centre of the screen and steps through the others; a diamond marks the target and arrows point to it off screen.

What you can change, no code: lock range, when the character faces the target, the diamond, arrows and sound, and how far an enemy chases before it gives up. See Tune targeting and What you can change.

How it fits together

Piece Asset or class Job
Target mode GA_XenoCore_TargetMode (UXenoCoreGameplayAbility_TargetMode) Holds the target; owns the indicator, off-screen arrows, HUD plates, palette and strafe facing. Holds Status.XenoCore.TargetMode while active.
Resolver and selection UXenoCoreTargetingStatics Get Current Target, candidate gathering, screen-order sorting, stepping.
Next / previous Input/Abilities/GA_XenoCore_TargetNext, GA_XenoCore_TargetPrev Send XenoCore.Event.SwitchTarget with a direction.
Exit Input/Abilities/GA_XenoCore_TargetModeExit Ends target mode on the B input: it cancels the ability tagged Ability.XenoCore.TargetMode (Cancel Abilities With Tag), and can only run while Status.XenoCore.TargetMode is on.
Off-screen arrows UXenoCoreOffscreenArrowComponent Chevrons at the screen edge pointing back at a target that left the view.
Indicator materials Battle/Targeting/M_XenoCore_TargetIndicator, M_XenoCore_TargetArrows The diamond and the arrows.
Target changed Message XenoCore.Targeting.Message.TargetChanged Seeker, new target, old target. Sent only by Set Current Target.

Enemies do not use this system. An enemy's target is decided by its AI controller (Get Aggro Target), and a companion fights the leader's current target.

Lifecycle

  1. Acquire. Pressing Target Next or Target Prev sends XenoCore.Event.SwitchTarget. If target mode is idle, the event starts it; the ability picks the candidate nearest the centre of the screen, horizontally, within Lock Acquire Range.
  2. Cycle. While active, the same event steps through candidates left to right as they appear on screen, wrapping at both ends. Only on-screen candidates can be cycled to.
  3. Keep. Every poll the lock is validated: the target must be alive and within Lock Keep Range, which is never less than Lock Acquire Range. A target that walks off screen is kept; the off-screen arrows point at it.
  4. Fight. Choosing an entry on the palette draws the weapon and starts the auto-attack or an art. See The combat loop.
  5. Kill. When the locked enemy dies and another enemy is still fighting the party, the lock moves to it instead of ending: one in view first, then the one with the most aggro on the leader, then the nearest. Enemies that are not part of the fight are never picked. The weapon stays drawn, so the party does not disarm mid-battle. Only when no enemy is left fighting does the kill end target mode.
  6. Exit. Target mode ends when you press Target Mode Exit, the last fighting enemy dies, or the lock becomes invalid. Every exit goes through one path, which sheathes the weapon, cancels the auto-attack, cancels any ally selection still open (the Art is not spent), clears the target (so listeners hear it) and removes the HUD.
  7. Hand over. When the player switches to another party member in battle, target mode is not exited. The old leader's target mode ends without sheathing or stopping its swing, and the new leader's target mode starts already locked on the same enemy, even if that enemy is off screen. The camera then eases onto the lock, as at the start of a fight. If the new leader's weapon is sheathed, it is drawn first. See Switching the controlled character.

A lost lock is logged, with the reason

When target mode ends because the target was lost, a warning target lock LOST (was ...: reason) is logged. The reason is one of dead, out of range (...), not on a different team or line of sight blocked by ..., naming the blocking actor (that reason only occurs while the lock check requires line of sight; see Require Line Of Sight in the settings below). A deliberate exit (B, a won fight, a switch) logs nothing. If the auto-attack seems to stop for no reason, look for this line first.

Facing while locked

Out of battle a character turns to face where it runs. In battle, target mode switches facing to the target, but only when that is what the player means:

  • The weapon must be drawn and the target within Strafe Max Range (400). It releases a little further out (Strafe Range Release Scale, 1.2×) so standing on the boundary does not flicker.
  • Standing still faces the target.
  • Moving straight away from the target (within Retreat Dot Threshold, about 25° either side) backpedals while facing it.
  • Moving forwards or sideways turns and runs normally.

This is re-evaluated every Strafe Evaluate Interval seconds rather than on target change, because the weapon is usually drawn after the target is picked.

Rotation settings always return to the Blueprint's authored values

Target mode, the auto-attack and arts each take control of a character's facing flags (Orient Rotation To Movement, Use Controller Rotation Yaw, Use Controller Desired Rotation) and give it back afterwards. They restore the values authored on the pawn's Blueprint class, not whatever was there before. So if you change facing at runtime from your own graph, the next fight will put it back. Change the defaults on the Blueprint instead. And if you write a new ability that turns the character, use Suppress Self Rotation and Restore Self Rotation from UXenoCoreLocomotionStatics, never save and restore the flags yourself.

Choosing an ally

An Art whose Target Type is One ally (Light Heal in the samples) does not cast at once. Confirming it opens the party cursor, the same cursor the battle switch uses:

  1. The cursor starts on the caster: a highlight on their HUD row and a small white ring on the floor under their body.
  2. D-pad up and down (arrow keys) move it through the party, wrapping. Any active member can be chosen, downed ones included.
  3. A (Space) casts the Art on the chosen member. B (leave target mode) cancels, and the Art is not spent.

Only one party cursor can be up at a time. While it is choosing an ally, the party switch is refused, and while the switch cursor is held, an ally Art cannot open it. The cursor's look is set on the party component; see Party.

Camera

When the fight starts (the weapon is drawn), the camera eases towards the target once, over Camera Focus Duration (0.3 s), and then the player owns the camera again. Nothing re-aims it afterwards. Set the duration to 0 to disable the ease.

The enemy side: engage and disengage

Enemies choose what to fight on their AI controller, AXenoCoreEnemyController (Characters/Enemies/Core/BP_AIC_XenoCore_Enemy), through Get Aggro Target. Each poll it answers, in order:

  1. Leash. If the enemy is engaged and more than Leash Radius (7,000) from where it started, it gives up completely and walks home.
  2. Provoked? An enemy that has not been provoked has no target, however close you stand. Being hit (any health loss) provokes it, and so does detecting the leader by its Detection (Sight, Sound or Ether; None waits to be attacked). In a spawner squad, provoking one member provokes the rest (link aggro). You can also call Notify Provoked yourself to start a fight.
  3. Who. The party member with the most aggro on this enemy; the nearest player pawn it may damage if it has no aggro yet.
  4. Distance. It engages inside Engage Radius (1,600) and stays engaged out to Engage Radius × Disengage Radius Scale (2.5). Two radii stop an enemy on the boundary from engaging and disengaging on alternate frames. An engaged enemy left behind beyond that gives up, heals and walks home.

Level gap. An enemy Ignore When Levels Below (6) or more levels below the leader does not detect it, unless Always Aggro is ticked or it is a Unique Monster. It still fights back if you attack it.

Is Engaged is the signal the enemy's health bar and AI use for "in a fight". All of these settings are on the enemy controller Blueprint under XenoCore › AI. See Enemies and AI.

Who it attacks is decided by aggro, not by who you are driving: a companion that deals damage or heals can draw the enemy away from the leader, and switching the controlled character does not move the enemy's attention. See Companion AI and aggro.

Why not Find Ability Spec From Class

Get Current Target finds the target-mode ability on the pawn by its ability tag, Ability.XenoCore.TargetMode, not by class.

Fails silently: looking an ability up by class

The ability system's Find Ability Spec From Class only matches the exact class. Every ability XenoCore grants is a Blueprint child of a C++ class, so passing the C++ class finds nothing, returns none and logs nothing. Use Get Target Mode Ability or Get Current Target, and in your own code find abilities by their ability tag.

Grant target mode once

A second grant of GA_XenoCore_TargetMode is a second instance with its own target, and Get Current Target returns whichever it finds first. The sample grants it only through each character's own ability set. Do not add it to a second set that the same character receives.

What you can change

Setting Where it lives What it does
Lock Acquire Range GA_XenoCore_TargetMode › XenoCore › Targeting › Range How far a target can be locked onto or cycled to. Default 3000 cm
Lock Keep Range same How far a locked target can go before the lock drops. Default 3000; kept at or above Lock Acquire Range by the editor, the data validator and its getter
Require Line Of Sight, Require On Screen Tick boxes on the Step Target From node (both) and the Is Target Still Valid node (Require Line Of Sight only) inside GA_XenoCore_TargetMode (open it, press Ctrl+F to find each node, and tick or untick the pin; then Compile and Save) Which enemies can be acquired and cycled
Strafe While Locked GA_XenoCore_TargetMode › XenoCore › TargetMode Turn facing-the-target on or off entirely.
Strafe Max Range, Strafe Range Release Scale same When facing the target starts and stops.
Retreat Dot Threshold, Strafe Stationary Speed same What counts as backing away and standing still.
Strafe Evaluate Interval same How often facing is re-decided.
Camera Focus Duration same The one-time ease at fight start.
Target Indicator Material, Target Indicator Size, Target Indicator Height Fraction, Target Indicator Screen Space Size same › XenoCore › Targeting The diamond over the target.
Target Acquired Sound same › XenoCore › Targeting Played on acquiring a target.
Offscreen Arrow Material, Offscreen Arrow Mesh, Arrow Screen Edge Inset, Arrow Camera Distance, Arrow Screen Size Fraction, Invert Arrow Direction same › XenoCore › Targeting The edge-of-screen arrows.
Target Plate Class, Player Plate Class, Arts Palette Class same › XenoCore › Targeting The battle HUD widgets it creates.
Approach Timeout, Approach Arrive Margin, Approach Stick Cancel same › XenoCore › Targeting › Approach Running in to use an art on a far target.

See Tune targeting.

Extending it

  • To read the target from anything (a widget, an art, an anim Blueprint), call Get Current Target with the pawn, or listen for XenoCore.Targeting.Message.TargetChanged.
  • To change how far lock-on reaches, set Lock Acquire Range and Lock Keep Range in Class Defaults. The graph reads them through Get Lock Acquire Range and Get Lock Keep Range.
  • To change who can be targeted otherwise (line of sight, on screen), duplicate GA_XenoCore_TargetMode into Content/MyGame/, change the node pins, and grant your copy in place of the original in your characters' ability sets.
  • Only Set Current Target may change the target. A target written any other way is invisible to the reticle, the HUD and the anim instance.
  • To change how the party AI picks targets, change the party StateTree rather than target mode. See Party.

Why it's built this way

For programmers: the design reasons
  • An ability, not a component. The lock has a start and an end, input, a HUD and a per-tick poll. A gameplay ability already has all of those, and instancing it per pawn makes "one target per pawn" true by construction.
  • Sorting in C++. Blueprint has no general sort node. Ordering candidates left to right on screen is the one piece that needed code; everything else is Blueprint-callable and used by the graph.
  • Horizontal angle, not screen distance. The camera looks slightly down, so a nearer enemy sits lower on screen. Scoring by full screen distance would favour a distant enemy near the horizon.
  • A switch hands the lock over. Ending the fight on a switch would sheathe both characters and reset the HUD every time the player changes who they drive; handing the lock over keeps the switch a free action, as in XC3.
  • Keep off-screen targets, cycle only on-screen ones. Dropping a lock when the enemy leaves the frame would make the arrows useless; cycling to an enemy you cannot see would be confusing.