Melee

Module PulseCombatMelee (depends on PulseCombat). A melee attack is a gameplay ability that plays a combo of steps. Every step has its own damage, hit shape and timing, and works with or without animation, so a prototype can fight before any montage exists.

Setup

  1. Make the attacker a combatant (ability system, UPulseHealthAttributeSet, UPulseCombatComponent, see Combat).
  2. Create a Pulse Attack data asset (UPulseAttackDefinition, Primary Asset Type PulseAttack) with the steps of the combo.
  3. Give the ability UPulseMeleeAttackAbility (or a Blueprint child) with the attack definition as source object of the spec, or set Attack on the ability. Without both, the ability plays InlineSteps (default: three hits with 10, 12 and 18 damage and timed windows).
  4. Bind the attack input to the ability (input ID or your own input code calling Press Attack). Pressing again during a combo continues it; the ability handles the input itself.

```cpp title=”Give a sword attack” FGameplayAbilitySpec spec(UPulseMeleeAttackAbility::StaticClass(), 1, INDEX_NONE, SwordAttack); AbilitySystem->GiveAbility(spec);


## Steps

| Field | Meaning |
| --- | --- |
| `Montage`, `MontageSection`, `PlayRate` | Optional animation. Without montage the step lasts `Duration`. |
| `bUseTimedWindows` | Use the times below even with a montage (ignore the notify states). |
| `Damage`, `DamageType`, `DamageTags`, `bCanCrit`, `DamageEffect` | Damage spec of a hit. `Pulse.Combat.Damage.Melee` and the definition's `DamageTags` are always added. |
| `Shape` | Where the step hits (below). |
| `HitEffects` | What a hit does after the damage (below). |
| `Duration`, `HitWindowStart/End`, `ComboWindowStart/End` | Timing in seconds when no montage drives it. |

`InputBuffer` of the definition: input up to this many seconds before the combo window opens is remembered.

### Timing from animation

With a montage, place the anim notify states **Pulse Melee Hit Window** (the hit check runs while it is active) and
**Pulse Combo Window** (input continues the combo) on the montage. The montage end finishes the step.

### Hit shapes

| Type | Use |
| --- | --- |
| `Sphere`, `Capsule`, `Box` | A shape at `Offset` / `Rotation` relative to the attacker (X = forward). Good for fists, claws, area swings and any pawn without weapon sockets. |
| `Sockets` | A sphere of `Radius` swept from the last to the current position of the two sockets `StartSocket` / `EndSocket` of the component tagged `ComponentTag` (on the attacker or an attached actor, e.g. the weapon). Fast swings are split into several sweeps (`MaxSweepStep` on the ability). The weapon actor becomes the damage causer. |

The hit check runs on the **authority** every `HitCheckInterval` seconds while the hit window is open. Every target is
hit at most once per step. By default only enemies are hit (`bOnlyHostile`, the hostility rule of the combat
settings), except targets whose `IPulseDamageable::IsHitByAnyAttacker` returns true (resource nodes); more filters go
into `HitFilters`. The hit check looks for the object types in `HitObjectTypes` (default `Pawn` and `PhysicsBody`).

## Hit effects and filters

Both are instanced structs from `PulseCombat` and are shared with ranged attacks:

| Hit effect (`FPulseHitEffect`) | Does |
| --- | --- |
| `FPulseHitEffect_Knockback` | Launches characters (or pushes simulated bodies) away from the attacker |
| `FPulseHitEffect_ApplyEffect` | Applies a gameplay effect to the target (poison, slow, stagger) |
| `FPulseHitEffect_SendEvent` | Sends a gameplay event to target and/or attacker |
| `FPulseHitEffect_GameplayCue` | Executes a gameplay cue at the hit (sparks, sound) |

`bOnlyIfDamaged` (default on) skips the effect when the target was immune or blocked everything.
`FPulseHitFilter_TargetTags` accepts only targets whose tags match a query. Write your own by deriving from
`FPulseHitEffect::Apply(const FPulseHitContext&)` or `FPulseHitFilter::Accepts`.

## Events

- `On Melee Hit` (dynamic) / `OnMeleeHitNative` on the ability, and the Blueprint hooks **On Hit** and
  **On Step Started**.
- The attacker gets the gameplay event `Pulse.Combat.Event.AttackHit` for every hit (e.g. to refund stamina).
- The damage itself goes through the normal pipeline: `On Damaged` of the target's combat component, messages.

While the ability runs the attacker has `Pulse.Combat.State.Attacking`; it is blocked by `Dead` and `Staggered`, so a
stagger interrupts a combo. Costs (stamina) and cooldowns are ordinary GAS cost and cooldown effects on the ability; other costs (items) are
`AttackCosts` (Pulse costs, `FPulseCostList`, see [Combat and inventory](./combat-inventory)).

## Magnetism and targets

When a step starts the attacker turns towards the attack target if it is within `MagnetismRange` and
`MagnetismAngle` (`bUseMagnetism`). The target is, in this order: the `Target` of the activation event data, the
lock-on target, the soft target of `UPulseTargetingComponent` (`Pulse::Combat::FindAttackTarget`).

## AI and scripts

An AI needs no player input: activate the ability on the server and pass the target in the event data.

```cpp
FGameplayEventData data;
data.Target = Enemy;
Pulse::Combat::PressAbilityInput(AbilitySystem, UPulseMeleeAttackAbility::StaticClass(), &data);

PressAbilityInput (Blueprint Press Attack) activates the ability when it is not running and otherwise presses its input, so calling it again continues the combo. It works for server controlled pawns; a player’s ability is predicted on the client and must be pressed there.

Multiplayer

The ability is local predicted: the owning client plays the montage at once, the server runs the hit check and deals the damage. Combo input reaches the server through the replicated input events of the ability.

Cheats

Command Does
PulseCombatGiveMelee [asset path] Gives the melee ability (inline combo without a path)
PulseCombatAttack [combo\|server] Presses the attack; combo presses three times in the combo windows

PulseCore plugin documentation.

This site uses Just the Docs, a documentation theme for Jekyll.