Radial destruction

Deliver one deterministic outward hit to every compatible destructible in a sphere, with constant or linear falloff and per-target seeds.

Radial destruction is a subsystem call, not a component. It finds compatible destructibles in a sphere and sends each one a deterministic outward hit.

USDFDestructionSubsystem -> Apply SDF Radial Destruction (Request) -> FSDFRadialDestructionResult

Generic by design

The request does not depend on an explosion Actor, an ability class or a damage-over-time system. A barrel, a spell, a collapsing ceiling and a trap can all issue the same call.

The request

FSDFRadialDestructionRequest:

FieldDefaultMeaning
OriginzeroWorld-space centre
Radius500.0Search radius
Damage100.0Damage at full strength, before falloff
DestructionPowerMediumCapability gate applied to every target
ImpulseStrength1000.0Impulse at full strength, before falloff
FalloffLinearConstant or Linear
MinimumFalloffMultiplier0.0Multiplier at the outer radius for Linear
InstigatornoneController credited
DamageCausernoneActor credited
DamageTypenoneOptional engine damage type
GameplayTagsemptyCarried into every generated hit
SourceObjectnoneOpaque spell, ability, attack or hazard reference
RandomSeed-1-1 generates one; any other value makes the whole event repeatable
PropagationDepth0Logical chain depth copied to every generated hit
IgnoredActorsemptyActors excluded from the query

Falloff

ModeBehaviour
ConstantEvery target inside the radius receives full Damage and ImpulseStrength
LinearDamage and impulse scale down with distance, reaching MinimumFalloffMultiplier at the outer radius

CalculateRadialFalloffMultiplier(Distance, Radius, Falloff, MinimumFalloffMultiplier) is exposed as a pure function, so you can preview the exact attenuation the subsystem will apply — useful for debug drawing.

Falloff never changes destruction power

Distance attenuation applies to Damage and ImpulseStrength only. DestructionPower is a discrete capability check and is never promoted or demoted by distance. A pot at the edge of a blast is either breakable by that blast or it is not.

Deterministic per-target seeds

Candidates are placed in stable path-name order, then each target’s seed is derived with CalculateRadialTargetSeed(AggregateSeed, StableTargetIndex).

With an explicit RandomSeed, the same explosion in the same scene produces the same variation choices on every target, every run. Set a seed when you need a scripted set piece to look identical in a cinematic, or when you are chasing a bug.

The result

FSDFRadialDestructionResult:

FieldMeaning
bExecutedThe query ran
bInvalidRadiusThe request was refused because the radius was not usable
RandomSeedThe aggregate seed actually used
QueriedActorCountActors returned by the overlap query
CompatibleTargetCountOf those, how many support destruction
DestroyedTargetCountHow many were destroyed
PresentationSuppressedCountHow many were destroyed with presentation suppressed by the frame budget
TargetsOne FSDFRadialTargetResult per compatible target

Each FSDFRadialTargetResult carries Target, Distance, FalloffMultiplier, the exact SentHit and the target’s full DestructionResult — enough to audit an entire blast without guessing.

PresentationSuppressedCount is the number worth watching while tuning: a large blast that destroys twenty objects in one frame will legitimately suppress some visual debris. See Performance.

One hit per Actor

The subsystem sends one hit per compatible Actor, not per primitive component. An Actor with several colliders is not damaged several times by one blast.

Ignored actors

IgnoredActors excludes specific Actors from the query. Typical uses: the barrel that produced the blast, the player who triggered it, or an object a script intends to destroy separately.

Blueprint example

Get World Subsystem (SDF Destruction Subsystem)
    -> Apply SDF Radial Destruction
         Request:
           Origin              = Get Actor Location
           Radius              = 400.0
           Damage              = 150.0
           Destruction Power   = Heavy
           Impulse Strength    = 1200.0
           Falloff             = Linear
           Minimum Falloff     = 0.25
           Instigator          = Get Instigator Controller
           Damage Causer       = self
           Ignored Actors      = [ self ]
           Random Seed         = -1
    -> break the result -> Destroyed Target Count -> award resources

C++ example

if (USDFDestructionSubsystem* Subsystem = GetWorld()->GetSubsystem<USDFDestructionSubsystem>())
{
    FSDFRadialDestructionRequest Request;
    Request.Origin = GetActorLocation();
    Request.Radius = 400.f;
    Request.Damage = 150.f;
    Request.DestructionPower = ESDFDestructionPower::Heavy;
    Request.ImpulseStrength = 1200.f;
    Request.Falloff = ESDFRadialFalloff::Linear;
    Request.MinimumFalloffMultiplier = 0.25f;
    Request.Instigator = GetInstigatorController();
    Request.DamageCauser = this;
    Request.IgnoredActors.Add(this);

    const FSDFRadialDestructionResult Result = Subsystem->ApplyRadialDestruction(Request);
    UE_LOG(LogTemp, Log, TEXT("Radial destroyed %d of %d compatible targets"),
        Result.DestroyedTargetCount, Result.CompatibleTargetCount);
}

Radial versus chain propagation

A radial call is something your code decides to do. A chain reaction is something a destroyed object does automatically because its profile allows it. They can combine: a barrel can issue a radial request on death and have propagation enabled, but in most scenes one of the two is enough — see Chain reactions.

Last updated: 2026-08-13

Type to search titles, sections and keywords.