Destruction hit
Every field of FSDFDestructionHit, and why Damage and DestructionPower are two separate concepts.
FSDFDestructionHit is the only payload the framework needs from gameplay code. It carries no
weapon class, no ability class and no combat framework assumption.
Fields
| Field | Type | Meaning |
|---|---|---|
Damage | float | Conventional damage, applied to health after the profile’s threshold and multipliers |
DestructionPower | ESDFDestructionPower | Discrete capability of the hit to break things |
ImpactLocation | FVector | World-space contact point |
ImpactNormal | FVector | Surface normal at the contact |
ImpactDirection | FVector | Direction the source was travelling toward the target |
ImpulseStrength | float | Physics impulse magnitude available to presentation |
Instigator | AController* | Controller responsible for the hit |
DamageCauser | AActor* | Actor that caused it |
DamageType | TSubclassOf<UDamageType> | Standard engine damage type, optional |
GameplayTags | FGameplayTagContainer | Free-form tags your systems can read back |
PhysicalMaterial | UPhysicalMaterial* | Optional surface material at the contact |
Weapon | UObject* | Generic optional source object; no weapon framework is required |
RandomSeed | int32 | -1 asks the receiving system to generate one |
PropagationDepth | uint8 | Chain depth; 0 means a root hit |
Damage and DestructionPower are separate
This is the central design decision of the runtime layer, and the one most likely to surprise.
Damageanswers how much health is removed.DestructionPoweranswers whether this kind of hit is capable of breaking this kind of object at all.
ESDFDestructionPower is an ordered enumeration:
| Value | Numeric |
|---|---|
None | 0 |
VeryLight | 1 |
Light | 2 |
Medium | 3 |
Heavy | 4 |
Massive | 5 |
A profile declares MinimumDestructionPower. A hit below that value is rejected regardless of how
much Damage it carries — a thousand points of arrow damage still does not topple a stone statue if
the statue requires Heavy.
The converse also holds. With bDestroyOnSingleValidHit, a fragile pot breaks on the first hit that
passes the power gate, even with very little damage. With bAllowPowerOverride and
InstantBreakPower, a sufficiently powerful hit destroys the object regardless of remaining health.
Worked example
A ceramic pot: MinimumDestructionPower = VeryLight, bDestroyOnSingleValidHit = true. A roll
contact carrying Damage = 0 and DestructionPower = Light destroys it. A wooden crate:
MaxHealth = 100, MinimumDestructionPower = Light. The same roll only damages it, and it takes
several hits to break.
Impact geometry
ImpactLocation, ImpactNormal and ImpactDirection have distinct jobs:
ImpactLocationpositions debris, audio, VFX and decals.ImpactNormalorients decals and any Niagara variation that opts into normal alignment.ImpactDirectiondrives the directional component of debris impulse and of the Geometry Collection break velocity.
ImpactDirection points from the attacker toward the target. Supplying the reverse makes debris
fly back toward the attacker.
Impulse
ImpulseStrength is a magnitude, not a vector. The profile decides how much of it is used:
DirectionalImpulseWeight, RandomImpulseWeight and UpwardImpulseWeight for the debris path, and
HitReactionImpulseMultiplier capped by MaximumHitReactionImpulse for non-breaking reactions.
The three hit sender components compute a bounded impulse for you from their own settings; when you build a hit by hand, you own that number.
Source references
Instigator, DamageCauser, DamageType, GameplayTags, PhysicalMaterial and Weapon are pure
carry-through. SDF does not interpret them — it stores them in the hit, echoes them in results and
requests, and lets your own listeners branch on them.
Common uses:
- tag a hit as
Attack.Heavyand read the tag in your audio delegate to select a bank; - pass the physical material to a middleware layer for surface-aware sound;
- pass a spell object as
Weaponand read it back inOnDestroyedto award resources.
Random seed
Every presentation decision that varies — sound variation, Niagara variation, decal variation, debris scatter, loot selection — is derived from a seed.
RandomSeed = -1(INDEX_NONE) asks the receiving system to generate one.- Any other value makes the result repeatable: the same hit produces the same variation choices.
The resolved seed is reported in FSDFDestructionResult::RandomSeed, so you can log it and replay a
specific presentation.
Propagation depth
PropagationDepth is 0 for a hit your gameplay code sends. Chain reactions increment it, and the
subsystem uses it to enforce the maximum depth. Leave it at 0 unless you are building your own
propagation logic. See Chain reactions.
Building a hit in Blueprint
- Add a
Make SDF Destruction Hitnode (FSDFDestructionHitis a Blueprint type). - Set
DamageandDestruction Power. - Feed
Impact LocationandImpact Normalfrom your trace or overlap result. - Compute
Impact Direction— usually the normalised vector from attacker to target. - Set
Impulse Strength. - Call
Apply Destruction Damageon the target’sSDF Destructiblecomponent.
If your systems already produce hit results, prefer the matching hit sender component (melee, collision, projectile) — they build the payload and handle duplicate suppression for you.
Building a hit in C++
FSDFDestructionHit Hit;
Hit.Damage = 25.f;
Hit.DestructionPower = ESDFDestructionPower::Medium;
Hit.ImpactLocation = HitResult.ImpactPoint;
Hit.ImpactNormal = HitResult.ImpactNormal;
Hit.ImpactDirection = (Target->GetActorLocation() - Attacker->GetActorLocation()).GetSafeNormal();
Hit.ImpulseStrength = 500.f;
Hit.Instigator = AttackerController;
Hit.DamageCauser = Attacker;
const FSDFDestructionResult Result = DestructibleComponent->ApplyDestructionDamage(Hit); Last updated: 2026-08-13