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.
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.
The ways to change a value
| Approach | When it changes | Use for |
|---|---|---|
| Edit the asset | Author time | The base value. Balance passes, tuning, anything that is the same for everyone |
| Author a second profile | Author time | A small number of fixed variants - a light and a heavy attack, two weapon classes. Simpler than any pin |
| A pin on the node | Runtime, per value | One number at a time: rank 3 sets radius to 600, a charge widens only the arc |
Shape Scale | Runtime, uniform | Everything bigger at once, from something that does not know the preset: a size buff, a growth mechanic, a notify-driven attack |
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.
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:
| Task | Pins | Also affected by Shape Scale |
|---|---|---|
| Crimson Selection: Socket Sweep | Socket Pairs (the whole array - sockets and per-pair radius) | Yes |
| Crimson Selection: Actor Sweep | Radius | Yes |
| Crimson Selection: Area | Radius, Half Height, Half Extent, Origin Socket, Origin Offset | Yes (the three dimensions) |
| Crimson Selection: Trace | Trace Type, Direction Mode, Custom Direction, Trace Length, Source Offset, Swept Radius, Swept Capsule Half Height, Swept Box Half Extent, Swept Rotation | Yes (the swept dimensions only - never the length) |
| Crimson Filter: Actor Class | Allowed Classes (the whole array) | No |
| Crimson Filter: Angle | Half Angle Degrees | No - an arc is not a size |
| Crimson Filter: Max Distance | Max Distance | No |
| Crimson Filter: Line Of Sight | Trace Height Offset | No |
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:
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.
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.
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 setup | Pins you get | Pins you do not |
|---|---|---|
Crimson Selection: Trace with Trace Type = Line | Trace Length, Source Offset | Swept 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 = Sphere | Radius | Half 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.
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.
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.
Shape Scale is still the right tool for a modifier that is not part of the attack at all.How values resolve
- The window duplicates the profile's preset. The copy starts at the asset's authored values.
- The node writes every pin you changed onto that copy. A pin still at its authored default writes nothing.
Shape Scale= the component's scale multiplied by the window's. Both default to 1, so either alone works and both together compound.- At query time each task uses its own value, then multiplies by
Shape Scaleif that value is a size.
| Authored | Pin | Shape Scale | Result | Why |
|---|---|---|---|---|
| 300 | - | - | 300 | Nothing changed; the copy still holds the asset's value |
| 300 | - | 1.5 | 450 | Uniform scale multiplies the authored value |
| 300 | 600 | - | 600 | The pin replaces the value, it does not add to it |
| 300 | 600 | 2.0 | 1200 | The pin sets the base, then scale multiplies it |
| 300 | - | 1.5 component x 2.0 window | 900 | Scales multiply: 300 x 1.5 x 2.0 |
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.
What cannot be varied
| Value | Why | What to do instead |
|---|---|---|
| Anything on the Targeting System's own tasks | They carry no ExposeOnTargeting metadata, and Epic's classes cannot be edited here | Use Crimson Selection: Area or Crimson Selection: Actor Sweep |
| Collision channels and object types | They select which world objects are queried at all, not how big the query is | Author a second preset |
| Which tasks a preset runs | Structural rather than numeric - a different task list is a different attack | Author a second preset |
| Dedup policy, target limits, Query Hz | They live on the profile, not the preset | Author a second profile |
| A persistent modifier with no attack of its own | A size buff does not know which preset it is widening | Shape Scale, or author the attack with the Crimson Hit Window node |
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.
// TotalAreaBonus is your own aggregate, e.g. 0.2 for +20%.HitDetection->SetShapeScale(1.f + TotalAreaBonus);
Integrating a modifier or augment system
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.
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
| Symptom | Cause | Fix |
|---|---|---|
| The node has no extra pins | The Profile pin is empty, or wired to a variable | Set it to a Hit Profile asset directly. A wired pin is unknowable at compile time |
| The node has no extra pins, profile is set | None of the preset's tasks expose anything | Check 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 nothing | It was changed on a client | Detection is server-only. The window only opens on the server |
| A value change does not apply mid-attack | The window was already open | Values are read once, at open. It applies to the next attack |
| Compile error: a pin no longer matches its Hit Profile | The preset's tasks changed after the node was placed | Refresh the node (right-click -> Refresh Nodes) to rebuild its pins |
| Pins disappeared after editing the preset | The node rebuilt against the new task list | Expected. Reconnect what you need; connections survive when task classes do |
| Everything is enormous | A pin and Shape Scale are both applied | They compound by design - the pin sets the base, the scale multiplies it |
| The shape vanished | A pin or scale resolved to zero or negative | Both 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