How-To: Vary An Attack's Values

Goal: change the numbers a Targeting Preset queries with - radius, arc, range - per attack and per actor, without authoring an asset for every combination.

Prerequisites
Quick Start, so you have a working preset and profile to modify.

Every request gets its own copy

A UTargetingPreset holds its tasks as Instanced objects, which means the task objects belong to the asset. Load the preset once and every character, enemy and projectile referencing it would share those same task objects - one Crimson Selection: Socket Sweep in memory, not one per sword. Writing a radius onto that would resize the attack for the entire game.

So the plugin never uses the asset directly. Opening a window duplicates the preset, and the request runs against that private copy. Writing to it is safe by construction: the asset is untouched, and two actors attacking in the same frame cannot see each other's numbers.

That is what makes the pins possible
Because each attack owns its preset, the Crimson Hit Window and Crimson Hit Query nodes can expose those values as ordinary input pins - the same way Spawn Actor from Class exposes a class's spawn parameters. Pick a Hit Profile on the node and the pins appear.

The ways to change a value

ApproachWhen it changesUse for
Edit the assetAuthor timeThe base value. Balance passes, tuning, anything that is the same for everyone
Author a second profileAuthor timeA small number of fixed variants - a light and a heavy attack, two weapon classes. Simpler than any pin
A pin on the nodeRuntime, per valueOne number at a time: rank 3 sets radius to 600, a charge widens only the arc
Shape ScaleRuntime, uniformEverything bigger at once, from something that does not know the preset: a size buff, a growth mechanic, a notify-driven attack
Reach for a second asset first
Pins earn their keep when a value is genuinely continuous - a percentage buff, a charge meter, a stat that scales. For two or three fixed variants, two or three profiles are cheaper to author and easier to read.

Anatomy of a preset

Open a Targeting Preset and you get one array, Targeting Task Set, holding instanced tasks in execution order. Selection tasks contribute candidates; filters remove them; sorts order what is left.

A Targeting Preset's task array. Order is execution order, and a selection task must come first.
Order is not cosmetic
Filters can only remove candidates. A preset whose first task is a filter resolves nothing at all, because there is nothing yet to filter - and it fails silently. UCrimsonHitProfile's Data Validation reports this, so save the profile after editing its preset.

1. Find the value you want to vary

A task property becomes a pin when it is marked ExposeOnTargeting. These ship exposed:

TaskPinsAlso affected by Shape Scale
Crimson Selection: Socket SweepSocket Pairs (the whole array - sockets and per-pair radius)Yes
Crimson Selection: Actor SweepRadiusYes
Crimson Selection: AreaRadius, Half Height, Half Extent, Origin Socket, Origin OffsetYes (the three dimensions)
Crimson Selection: TraceTrace Type, Direction Mode, Custom Direction, Trace Length, Source Offset, Swept Radius, Swept Capsule Half Height, Swept Box Half Extent, Swept RotationYes (the swept dimensions only - never the length)
Crimson Filter: Actor ClassAllowed Classes (the whole array)No
Crimson Filter: AngleHalf Angle DegreesNo - an arc is not a size
Crimson Filter: Max DistanceMax DistanceNo
Crimson Filter: Line Of SightTrace Height OffsetNo
Box extents are a real vector
Half Extent arrives as an FVector pin, so a box can be stretched on one axis alone. Use Shape Scale when you want to grow a box while keeping its proportions.

2. Exposing a value on your own task

Nothing to do if you are using the tasks above. To expose a property on a task you wrote, add the marker to its UPROPERTY:

cpp
UPROPERTY(EditAnywhere, Category = "Dimensions", meta = (ExposeOnTargeting, ClampMin = "0.1"))
float Radius = 300.f;

Every profile whose preset uses that task grows the pin. Any Blueprint-settable type works: floats, vectors, names, enums, structs, arrays.

Epic's own tasks cannot be exposed
UTargetingSelectionTask_AOE and UTargetingSelectionTask_Trace carry no Crimson metadata, so they always run at their authored values. Use Crimson Selection: Area, Crimson Selection: Trace, Crimson Selection: Socket Sweep or Crimson Selection: Actor Sweep for anything that needs to vary.

3. Set the value on the node

Add Crimson Hit Window (or Crimson Hit Query) to your ability graph and set its Profile pin to a Hit Profile asset. The node immediately grows one pin per exposed value. Wire whatever computes the number - an ability level, a charge alpha, a stat lookup - straight into it.

Crimson Hit Window with an area profile selected. Radius, Half Height and Origin Offset come from the preset's Crimson Selection: Area task; a pin left at its authored default costs nothing.
The Profile pin must be a literal
Wiring a variable into Profile means the asset is unknown until the game runs, so there is nothing to build pins from. The node compiles with a warning and the attack uses the preset's authored values.

Which pins appear

The node only grows a pin for a value that is relevant to how the task is set up. A property the task's own Details panel would hide is hidden on the node too - the node reads the same EditCondition the panel does, so the two cannot drift apart.

Task setupPins you getPins you do not
Crimson Selection: Trace with Trace Type = LineTrace Length, Source OffsetSwept Radius, Swept Capsule Half Height, Swept Box Half Extent, Swept Rotation - a line has no shape to size
Crimson Selection: Trace with Direction Mode = Control Rotation-Custom Direction - nothing reads it in that mode
Crimson Selection: Area with Shape = SphereRadiusHalf Height, Half Extent

Trace Type and Direction Mode are pins themselves, and they are read from the pin before the asset. Change Trace Type to Sphere on the node and a Swept Radius pin appears immediately, keeping every connection and value you had already set.

Wiring one of those pins gives control back to the asset
A pin driven by a variable has no value until the graph runs, so the node cannot know which other pins to show. When Trace Type is wired, the dependent pins fall back to whatever the preset was authored with and all of them reappear - which is what you want, because any of them could be the one that matters at runtime.

Editing the profile, the preset, or a task inside it is tracked too: every open node using that asset rebuilds itself. An edit that leaves the pin list identical changes nothing, so tuning a trace length does not dirty every Blueprint that references the profile.
A pin you expected is missing
Check the task's Details panel first. If the property is greyed out or hidden there, the node is agreeing with it, and the fix is on the task - set Trace Type to the shape you actually want. If the property is editable on the task but has no pin, see Troubleshooting at the bottom of this page.

Shape Scale, for what pins cannot reach

Shape Scale multiplies every dimension of every Crimson shape, on top of whatever the pins resolved to. It covers the case a node pin structurally cannot: a persistent buff - a size potion, a growth mechanic - that has no idea which preset it is widening.

On the server: Get Component By Class (Crimson Hit Detection Component) -> Set Shape Scale (New Scale = 1.25). Set it back to 1 when the buff is removed. For one attack only, split the Params pin on Open Hit Window and set Shape Scale there.

Animation notifies use Shape Scale, not pins
A notify is a static asset and cannot hold a per-activation value. It does not need to: the profile it fires is armed by the ability's Crimson Hit Query node, and that node's exposed pins are written onto the preset copy that gets armed. So a montage-driven attack scales with a charge level exactly like a node-driven one.

Shape Scale is still the right tool for a modifier that is not part of the attack at all.

How values resolve

  1. The window duplicates the profile's preset. The copy starts at the asset's authored values.
  2. The node writes every pin you changed onto that copy. A pin still at its authored default writes nothing.
  3. Shape Scale = the component's scale multiplied by the window's. Both default to 1, so either alone works and both together compound.
  4. At query time each task uses its own value, then multiplies by Shape Scale if that value is a size.
AuthoredPinShape ScaleResultWhy
300--300Nothing changed; the copy still holds the asset's value
300-1.5450Uniform scale multiplies the authored value
300600-600The pin replaces the value, it does not add to it
3006002.01200The pin sets the base, then scale multiplies it
300-1.5 component x 2.0 window900Scales multiply: 300 x 1.5 x 2.0
Values are read when the window opens, not per query
Changing Shape Scale mid-swing does not affect a window that is already open. That is deliberate - an attack's size should be decided when it starts, exactly like its arc - but it means a buff that lands mid-animation applies to the next attack, not the current one.

4. Verify it

Console: Crimson.HitDetection.Debug 1. The queried shape draws in blue, so a size change is immediately visible.

The same profile drawn at Shape Scale 1 and 2. Blue is the queried shape, green a reported hit, red a candidate a filter rejected.
Verify
Set a radius pin to something absurd - 2000 - and confirm the blue shape balloons. Then have two actors attack in the same frame with different values and confirm each draws its own size: that is the whole point of the private copy.

What cannot be varied

ValueWhyWhat to do instead
Anything on the Targeting System's own tasksThey carry no ExposeOnTargeting metadata, and Epic's classes cannot be edited hereUse Crimson Selection: Area or Crimson Selection: Actor Sweep
Collision channels and object typesThey select which world objects are queried at all, not how big the query isAuthor a second preset
Which tasks a preset runsStructural rather than numeric - a different task list is a different attackAuthor a second preset
Dedup policy, target limits, Query HzThey live on the profile, not the presetAuthor a second profile
A persistent modifier with no attack of its ownA size buff does not know which preset it is wideningShape Scale, or author the attack with the Crimson Hit Window node
The other way to vary a value: override it
Crimson Selection: Trace is Blueprintable and resolves every value it uses through a BlueprintNativeEvent - Get Trace Length, Get Swept Trace Radius, Get Trace Direction and the rest. A subclass can compute any of them from the request handle at query time.

Pins and overrides answer different questions. A pin is per-attack and authored where the attack is: the ability graph. An override is per-task and applies to every attack using that task, which is what you want when the value comes from game state the graph does not have. See How-To: Area Attacks and Hitscan -> 2. Aim the trace for the override in both audiences.

Worked examples

A skill rank that sets radius

Three ranks, each with its own radius, from one profile and one preset. On Crimson Hit Query, wire a Select Float (indexed by the ability's rank) into the Radius pin. No tags, no component state - the value travels with the attack that uses it.

A charged attack that grows while held

Wire a Lerp from your charge alpha into the Radius pin - 300 at no charge, 700 at full. The charge finishes before the swing starts, so the value is known when the window opens, which is exactly when it is read.

A percentage area buff from gear

Shape Scale, not a pin. A percentage is inherently relative, so it should multiply whatever the base happens to be - including a base a rank pin already set. And the buff has no business knowing which preset it is widening. Recompute and set it whenever the equipment set changes.

cpp
// TotalAreaBonus is your own aggregate, e.g. 0.2 for +20%.
HitDetection->SetShapeScale(1.f + TotalAreaBonus);

Integrating a modifier or augment system

This plugin does no stacking
A pin is the number the task will use. There is no add-versus-multiply, no ordering, no source tracking, no diminishing returns. If five modifiers each want to change a radius, whatever owns them resolves that into one number before the graph reaches the node.

That is deliberate. Stacking is a property of the system that owns the modifiers, every game's rules differ, and a second opinion baked in here would fight yours.

The integration is therefore always the same shape: resolve, then wire. Your system produces a final number; you plug it into the pin. Because it is an ordinary Blueprint connection, the source of every value is visible in the graph rather than implied by a tag matching somewhere off-screen.

Using CrimsonAbilitySystem?
Its augment system already performs exactly that resolution: augments apply add, multiply and override operations, and the ability holds the resolved value per FGameplayTag. Wire Get Configurable Value (with the Ability.Property.* tag your augments modify) straight into the pin.

Neither plugin references the other, and the connection is right there in the graph. (CrimsonAbilitySystem - a separate plugin.)

Troubleshooting

SymptomCauseFix
The node has no extra pinsThe Profile pin is empty, or wired to a variableSet it to a Hit Profile asset directly. A wired pin is unknowable at compile time
The node has no extra pins, profile is setNone of the preset's tasks expose anythingCheck the task list. Epic's tasks never expose; swap in the Crimson task for that shape. Then check the value is relevant to how the task is configured - a Swept Radius grows no pin while Trace Type is Line
A pin exists but changing it does nothingIt was changed on a clientDetection is server-only. The window only opens on the server
A value change does not apply mid-attackThe window was already openValues are read once, at open. It applies to the next attack
Compile error: a pin no longer matches its Hit ProfileThe preset's tasks changed after the node was placedRefresh the node (right-click -> Refresh Nodes) to rebuild its pins
Pins disappeared after editing the presetThe node rebuilt against the new task listExpected. Reconnect what you need; connections survive when task classes do
Everything is enormousA pin and Shape Scale are both appliedThey compound by design - the pin sets the base, the scale multiplies it
The shape vanishedA pin or scale resolved to zero or negativeBoth are clamped to a minimum, but a value near zero still hits nothing. Check the source of the number

See also

  • How-To: Area Attacks and Hitscan
  • Concept: Windows, Shapes and Filters
  • API Reference