Skip to content
CRUSHFORMV1.1.0
GET IT ON FAB

WORLDDEBRIS

Debris

When a fence section or a window breaks, its baked pieces fly out. They land, roll, lie for a while and sink away. Debris is the cosmetic part of a break. It does not replicate: each machine throws its own pieces when it sees the break.

Debris pieces are physics bodies. How cars and pawns meet them is set by the definition and by the collision profile, as the sections below describe.

A sedan seen from behind on the Proving Ground, with picket fence pieces in the air and lying on the ground around it.
Picket pieces after a break, lying on the ground and in the air around the sedan.

Debris is pooled. The UCFDebrisSubsystem world subsystem keeps a fixed set of piece components and reuses them. When a unit breaks, the subsystem takes free pieces from the pool and throws the unit’s baked pieces. The pieces sit on the same local machine only.

  • Who simulates it. Debris is client-side. A dedicated server never creates the subsystem, so it spawns no pieces.
  • Where it spawns. A break farther than DebrisMaxSpawnDistanceCm (10000 cm) from the local camera spawns no debris.
  • The throw. Pieces near the impact point inherit more of the hitting body’s velocity. Pieces far from it mostly topple. A piece that is at the impact point takes InheritVelocityFraction (0.6) of the body’s speed, plus ScatterSpeedCmS (300 cm/s) outward and up. The push falls off over ImpactFalloffCm (150 cm).
  • Collision. A piece collides with the world, with intact props and with other pieces, but not with pawns. Which object type it uses is set by the Debris Collision Profile in the project settings. A definition with bDebrisCollidesWithDebris off makes its pieces ignore other pieces.
  • Vehicles. Vehicle bodies pass through a piece, unless the definition sets bDebrisPushedByVehicles. Then a car pushes the piece one way for DebrisVehicleContactSeconds (3.5 s) after the break. A piece that lies on a vehicle keeps being pushed until it is off it. A pushed piece never counts as a hit on the car.
  • Lifetime. A piece that falls asleep lies still for DebrisRestSeconds (3 s), then sinks for DebrisSinkSeconds (1 s): it goes straight down by its own size, its longest edge as scaled plus 10 cm, shrinking to a fifth of its size, and is hidden at the end. DebrisLifetimeSeconds (8 s) is a hard cap on its life, resting or not.
  • Budget. The game keeps at most MaxLiveDebrisPieces (96) pieces; the oldest is recycled beyond that. Pieces of a definition whose debris lasts until the unit respawns (bDebrisLastsUntilRespawn) are counted apart, up to MaxPersistentDebrisPieces (64).

The pieces that a break throws are the baked pieces of the unit’s definition. See Fences and props for how a definition is baked.

Debris has no asset of its own. Each breakable definition sets its own debris, and the project settings set the budget for all of it.

  1. In the Content Browser, open the fence definition, DA_CF_FencePicket, from Plugins › Crushform Content › Fences (or your own definition).
  2. In the Debris category, set Debris Lifetime Seconds, Debris Rest Seconds and Debris Sink Seconds. Turn on Debris Pushed by Vehicles if cars should push the pieces.
  3. Open Project Settings › Plugins › Crushform Breakable. In the Debris group, set Max Live Debris Pieces and Debris Collision Profile. The profile’s tooltip asks for one that rests on the world and ignores pawns. The default is None, which makes a piece physics-only: no trace, sweep or overlap finds it.
Debris
Max Live Debris Pieces96
Max Persistent Debris Pieces64
Debris Max Spawn Distance Cm10000.0
Debris Impact Cooldown Seconds0.25
Debris Min Impulse Per Kg50.0
Debris Impulse Per Kg for Full Intensity600.0
Debris Collision ProfileNone
The Debris group in Project Settings, under Plugins > Crushform Breakable.

The subsystem has no Blueprint node, so a Blueprint cannot change the pool or spawn pieces. It can read a definition’s Debris values, because they are BlueprintReadOnly. The graph below holds a fence definition in a variable and prints its Debris Lifetime Seconds when a custom event fires.

The graph holds a fence definition in a variable and prints its Debris Lifetime Seconds when a custom event fires.

A game that wants to read or clear the pool does it in C++:

#include "CFDebrisSubsystem.h"
void ReportAndClearDebris(const UObject* WorldContext)
{
if (UCFDebrisSubsystem* Debris = UCFDebrisSubsystem::Get(WorldContext))
{
UE_LOG(LogTemp, Log, TEXT("Live debris pieces: %d"), Debris->GetLivePieceCount());
Debris->ReleaseAllPieces();
}
}

The signatures are static UCFDebrisSubsystem* Get(const UObject* WorldContext), int32 GetLivePieceCount() const and void ReleaseAllPieces(). ReleaseAllPieces returns every live piece to the pool at once, without sinking.

A game that gives the pool its own camera and feedback implements ICFBreakableHost in C++ and registers it with SetHost. The interface has two methods, TryGetBreakableViewLocation(FVector&) const, which gives the point the debris is culled from, and PlayBreakableFeedback(const FCFBreakableFeedback&), which plays the sound and effect of a break. It is C++ only: it cannot be implemented in a Blueprint.

#include "CFBreakableHost.h"
#include "CFDebrisSubsystem.h"
class FMyBreakableHost : public ICFBreakableHost
{
public:
virtual bool TryGetBreakableViewLocation(FVector& OutLocation) const override;
virtual void PlayBreakableFeedback(const FCFBreakableFeedback& Feedback) override;
};
// The pool does not own the host: keep it alive while it is registered.
void RegisterBreakableHost(const UObject* WorldContext, ICFBreakableHost* Host)
{
if (UCFDebrisSubsystem* Pool = UCFDebrisSubsystem::Get(WorldContext))
{
Pool->SetHost(Host);
}
}

The C++ block needs the CrushformBreakable module in your Build.cs (see Installation). Unless Use Default Breakable Host is off in the Crushform Impact Feedback settings, the plugin’s default host, UCFImpactBreakableHost, registers itself and maps the breaks to impact events. See Impact feedback.

A primitive that stands for one unit of a units component implements ICFBreakableUnitPart in C++, through GetBreakableUnits. That is how a hit on the primitive is traced back to its unit. It is C++ only too.

The debris values are on the breakable definition, in the Debris category. The budget and the collision profile are in the project settings. The defaults are the plugin’s.

PropertyWhat it doesDefault
UCFBreakableDefinition::bDebrisLastsUntilRespawnPieces lie until the unit stands again, instead of sinking.false
UCFBreakableDefinition::bDebrisPushedByVehiclesVehicle bodies push the pieces, one way, for the contact time.false
UCFBreakableDefinition::DebrisVehicleContactSecondsHow long after the break vehicles push the pieces. 0 means for as long as they lie.3.5
UCFBreakableDefinition::bDebrisCollidesWithDebrisWhether a piece collides with other pieces.true
UCFBreakableDefinition::DebrisLifetimeSecondsThe hard cap on a piece’s life, resting or not.8
UCFBreakableDefinition::DebrisRestSecondsHow long a piece lies still before it sinks.3
UCFBreakableDefinition::DebrisSinkSecondsHow long a piece takes to sink away.1
UCFBreakableDefinition::InheritVelocityFractionShare of the hitting body’s velocity the piece at the impact point gets.0.6
UCFBreakableDefinition::ScatterSpeedCmSExtra outward and upward speed at the impact point, in cm/s.300
UCFBreakableDefinition::ImpactFalloffCmPieces this far from the impact point get the weakest throw.150
UCFBreakableSettings::MaxLiveDebrisPiecesLive pieces per world. The oldest is recycled beyond this.96
UCFBreakableSettings::MaxPersistentDebrisPiecesLive pieces of definitions whose debris lasts until respawn.64
UCFBreakableSettings::DebrisMaxSpawnDistanceCmA break farther than this from the local camera spawns no debris.10000
UCFBreakableDefinition::MaxAngularSpeedDegSThe highest spin a thrown piece gets, in degrees per second.540
UCFBreakableSettings::DebrisCollisionProfileThe collision profile of the pieces.None
UCFBreakableSettings::DebrisImpactCooldownSecondsThe shortest time between two hit feedbacks of one piece.0.25
UCFBreakableSettings::DebrisMinImpulsePerKgThe impulse per kilogram a piece hit needs before it plays feedback.50
UCFBreakableSettings::DebrisImpulsePerKgForFullIntensityThe impulse per kilogram at which a piece hit plays at full strength.600

In any build except Shipping, open the console with the tilde key.

  • stat CrushformDebris shows the debris cycles. The pool’s live count is GetLivePieceCount, which the C++ example above reads.
  • Break a fence section in Lvl_ProvingGround. Pieces fly out, land, lie and sink.
  • Drive a car into a picket that a definition has set to bDebrisPushedByVehicles. The car pushes the piece for DebrisVehicleContactSeconds, then drives through it.
  • Open the debug panel and use Clear debris under World. Every piece goes back to the pool at once. See Debug mode.

Cause. The definition has not been baked, and a definition with no baked pieces spawns none. Or the break happens farther than DebrisMaxSpawnDistanceCm (10000 cm) from the local camera, or on a dedicated server, which never spawns debris.

Fix. Bake the definition with Bake Pieces. Stand closer to the break to test it. A dedicated server does not show debris by design: the clients show it.

Cause. The pool is full. Beyond MaxLiveDebrisPieces (96) the oldest piece is recycled, and a piece that is past DebrisLifetimeSeconds (8 s) is removed even if it is still lying there.

Fix. Raise Max Live Debris Pieces, or set DebrisLifetimeSeconds higher. For pieces that should stay until the unit respawns, turn on bDebrisLastsUntilRespawn, and raise Max Persistent Debris Pieces if the budget for them runs out.

Cause. bDebrisPushedByVehicles is off, which is the default. Or it is on, and DebrisVehicleContactSeconds has passed, after which vehicles pass through the piece again.

Fix. Turn Debris Pushed by Vehicles on for pieces that should move under a car, and set Debris Vehicle Contact Seconds to how long the push should last.

Cause. Pieces collide with the world, intact props and each other, but not with pawns. That is the design, and the Debris Collision Profile sets it.

Fix. To have pieces stop a pawn, set Debris Collision Profile to a profile that blocks pawns. Then check that the pieces still rest on the world.

A piece hit plays the impact tag the definition names as Debris Impact Tag, or Crushform.Impact.Prop.Debris when that is empty. The cooldown and impulse limits above decide when it plays. For the tags and their sounds, see Impact feedback.