Roll and collision integration

Drive destruction from movement — rolls, dashes and charges — with USDFCollisionHitSenderComponent, a minimum speed gate and bounded impulse mapping.

USDFCollisionHitSenderComponent bridges movement-driven contacts — a dodge roll through a pot, a charging enemy through a barricade — to SDF. Contact detection stays in your movement code.

Setup

  1. Add SDF Collision Hit Sender to the moving Actor.
  2. Configure HitSettings.
  3. Call Begin SDF Collision Window when the action starts (roll, dash, charge).
  4. Call Send SDF Collision Hit for each contact your capsule sweep or overlap reports.
  5. Call End SDF Collision Window when the action ends.

No tick and no timer. The window is explicit state, like the melee swing.

Hit settings

FSDFCollisionHitSettings:

PropertyDefaultMeaning
MinimumContactSpeed200.0 cm/sContacts slower than this are rejected before reaching the target
ImpulsePerSpeedUnit1.0Converts source speed into the payload’s impulse
MaximumImpulseStrength1200.0Hard cap on the computed impulse
DamageTypenoneOptional engine damage type
GameplayTagsemptyTags carried through to listeners
bRequireActiveCollisionWindowtrueContacts are accepted only inside an opened window
bSuppressRepeatedActorsPerWindowtrueOne Actor receives at most one hit per action

Speed, damage and power are independent

SendCollisionHit takes Damage and DestructionPower as explicit parameters, decided by the caller for that action. Speed does not scale them.

Speed does exactly two things:

  1. it gates the contact through MinimumContactSpeed;
  2. it produces the impulse, as Speed × ImpulsePerSpeedUnit, clamped to MaximumImpulseStrength.

Why this split

A slow, deliberate shoulder charge should be able to smash a door that a fast, weightless dodge roll cannot. Tying destructive capability to raw velocity would make that impossible to express.

Sending a contact

Send SDF Collision Hit parameters:

ParameterNotes
TargetActorOptional when HitResult contains an Actor
HitResultSupplies impact point and normal
SourceVelocityWorld velocity in cm/s — usually GetVelocity()
DamageChosen per action
DestructionPowerChosen per action
InstigatorControllerController credited with the hit
DamageCauserThe moving Actor
SourceObjectAny UObject; for example the montage or ability driving the move
RandomSeed-1 to generate one

The direction of the payload is derived from the velocity, so debris scatters the way the body was actually moving.

Result: FSDFCollisionDeliveryResult — bDelivered, bSuppressedAsDuplicate, bRejectedBecauseWindowInactive, bRejectedBelowMinimumSpeed, bTargetSupportsDestruction, ContactSpeed, Target, SentHit and DestructionResult.

ContactSpeed is reported even when the contact was rejected, which makes tuning MinimumContactSpeed straightforward: log a few real rolls and read the numbers.

Duplicate protection

A capsule sliding along a crate generates overlap events every frame. With bSuppressRepeatedActorsPerWindow enabled, only the first contact per Actor per window is delivered. Begin SDF Collision Window clears that history, so the next roll can hit the same object again.

Worked profiles

Three movement states, one component:

StateSpeedDamagePowerResult on a fragile potResult on a crate
Walkingbelow MinimumContactSpeed——Rejected before delivery — no breakNo effect
Runningabove the gatelowVeryLightBreaks if the pot is fragileReaction or minor damage
Rollabove the gatemoderateLightBreaksDamage; several rolls to break

The exact numbers belong to your game. What the framework guarantees is that the walking case never reaches the destructible at all, and that the roll and run cases differ by intent rather than by accident of velocity.

Blueprint example

Roll montage starts
    -> SDF Collision Hit Sender -> Begin SDF Collision Window

Capsule sweep reported a Hit Result
    -> SDF Collision Hit Sender -> Send SDF Collision Hit
         Target Actor       = Hit Result -> Hit Actor
         Hit Result         = Hit Result
         Source Velocity    = Get Velocity
         Damage             = 10.0
         Destruction Power  = Light
         Instigator         = Get Controller
         Damage Causer      = self
         Source Object      = RollMontage
         Random Seed        = -1

Roll montage ends
    -> SDF Collision Hit Sender -> End SDF Collision Window

C++ example

CollisionSender->BeginCollisionWindow();

const FSDFCollisionDeliveryResult Delivery = CollisionSender->SendCollisionHit(
    HitResult.GetActor(),
    HitResult,
    GetVelocity(),
    /* Damage */ 10.f,
    ESDFDestructionPower::Light,
    GetController(),
    this,
    RollMontage,
    /* RandomSeed */ -1);

if (Delivery.bRejectedBelowMinimumSpeed)
{
    UE_LOG(LogTemp, Verbose, TEXT("Contact at %.0f cm/s was below the gate"), Delivery.ContactSpeed);
}

CollisionSender->EndCollisionWindow();

Listening to deliveries

OnCollisionHitDelivered broadcasts every delivery result, which is a convenient place to trigger movement feedback — a small camera shake when a roll actually smashes something.

Last updated: 2026-08-13

Type to search titles, sections and keywords.