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
- Add SDF Collision Hit Sender to the moving Actor.
- Configure
HitSettings. - Call
Begin SDF Collision Windowwhen the action starts (roll, dash, charge). - Call
Send SDF Collision Hitfor each contact your capsule sweep or overlap reports. - Call
End SDF Collision Windowwhen the action ends.
No tick and no timer. The window is explicit state, like the melee swing.
Hit settings
FSDFCollisionHitSettings:
| Property | Default | Meaning |
|---|---|---|
MinimumContactSpeed | 200.0 cm/s | Contacts slower than this are rejected before reaching the target |
ImpulsePerSpeedUnit | 1.0 | Converts source speed into the payload’s impulse |
MaximumImpulseStrength | 1200.0 | Hard cap on the computed impulse |
DamageType | none | Optional engine damage type |
GameplayTags | empty | Tags carried through to listeners |
bRequireActiveCollisionWindow | true | Contacts are accepted only inside an opened window |
bSuppressRepeatedActorsPerWindow | true | One 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:
- it gates the contact through
MinimumContactSpeed; - it produces the impulse, as
Speed × ImpulsePerSpeedUnit, clamped toMaximumImpulseStrength.
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:
| Parameter | Notes |
|---|---|
TargetActor | Optional when HitResult contains an Actor |
HitResult | Supplies impact point and normal |
SourceVelocity | World velocity in cm/s — usually GetVelocity() |
Damage | Chosen per action |
DestructionPower | Chosen per action |
InstigatorController | Controller credited with the hit |
DamageCauser | The moving Actor |
SourceObject | Any 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:
| State | Speed | Damage | Power | Result on a fragile pot | Result on a crate |
|---|---|---|---|---|---|
| Walking | below MinimumContactSpeed | — | — | Rejected before delivery — no break | No effect |
| Running | above the gate | low | VeryLight | Breaks if the pot is fragile | Reaction or minor damage |
| Roll | above the gate | moderate | Light | Breaks | Damage; 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