WORLDIMPACT FEEDBACK
Impact feedback
What it does
Section titled “What it does”When a car hits a wall, a fence, a tree or a window, it makes a sound and a spark. When a breakable piece lands, it makes a thud. Impact feedback is the part of Crushform that plays these. It turns a hit into an impact event, looks up what that event should sound and look like, and plays it at the place of the hit.
With the LogHits console variable on, the plugin reports every hit it judges. In the editor’s play session each hit leaves a marker for 5 seconds: a sphere at the point of impact with an arrow along the surface normal. It is green when the impact plays, yellow for a hit within a steady contact, and red for a hit below the minimum. Each judged hit also writes one line to the log, in the category LogCrushformImpact, in this form:
<owner>: <component> (bone <bone>) hit by <actor> / <component>, impulse N, support N, mass N kg, other mass N kg, normal Z N, intensity N at <point>: <verdict>The verdict is played, below minimum or steady contact, suppressed.
How it works
Section titled “How it works”Every impact is a gameplay tag, such as Crushform.Impact.Prop.Break.Wood, played at a location. The UCFImpactFeedbackSubsystem does the rest:
- It finds the row for the tag in the active impact set. If the set has no row for that exact tag, it uses the row of the closest parent tag that has one. If no row matches, nothing plays.
- It plays one sound from the row at random, and spawns the row’s Niagara effect with its
Intensityparameter set. - It scales the volume between the row’s Volume by Intensity values and picks a pitch from its Pitch Range.
- It applies the row’s filters: a hit below Min Intensity plays nothing, a source that played recently waits out its Cooldown Seconds, and while Max Concurrent Voices of the row are busy, a new impact plays its effect but no sound. Across the whole plugin, at most Max Sounds Per Frame sounds (2 by default) start in one frame: the rest wait, strongest first, for later frames, and a sound still waiting after Sound Queue Seconds (0.15 s) is dropped. Starting the sounds of a crash that makes many at once in one frame would cost a hitch, so they are spread over a few frames instead. Effects are never queued.
The impact set is a UCFImpactFeedbackSet data asset. The project’s default is /Crushform/Impact/DA_CF_ImpactFeedback, with a row for each of the plugin’s tags. A project can make its own set and point the Default Set at it.
Impacts come from components that sit on a body. You add them in the Blueprint editor’s Add menu, where all three are listed under Custom, not under Crushform:
UCFImpactFeedbackComponentreports the hits of the primitive it observes, with the Event Tag it is given (Crushform.Impact.Hitby default). It observes nothing until you give it a primitive withSetObservedPrimitive, which is C++ only. A hit is judged by its impulse per kilogram of the body. Below Min Impulse Per Kg (50) it is silent, and it is at full strength at Impulse Per Kg for Full Intensity (600). A steady contact, such as a body resting on the ground, does not repeat the impact.UCFNetImpactFeedbackComponentobserves its owner’s root primitive by itself, and it also relays a hit to the other players. A relay normally waits at least Min Relay Interval Seconds (0.5 s), and comes sooner for a markedly stronger hit.UCFPartImpactFeedbackComponentplays the slam of a hinged part when it reaches an end of its travel. A part that slams shut into the closed end plays Slam Event Tag,Crushform.Impact.Part.Slamby default. A part flung wide into the open end plays Open Slam Event Tag,Crushform.Impact.Part.Slam.Openby default, and an impact set without a row for that tag plays thePart.Slamrow.
A vehicle gets these from its adapter. A breakable definition names its own tags, and an empty one plays the plugin’s default.
The plugin declares 19 impact tags, in CFImpactTags:
| Tag | Played when |
|---|---|
Crushform.Impact | The root of the impact events. |
Crushform.Impact.Hit | A body with an impact feedback component hits something. |
Crushform.Impact.Vehicle.Crash | A vehicle’s body strikes something solid. |
Crushform.Impact.Prop.Break | A breakable prop that is not glass breaks. |
Crushform.Impact.Prop.Break.Wood | A wooden prop breaks apart, such as a wooden fence section. |
Crushform.Impact.Prop.Break.Metal | A metal prop breaks off whole, such as a chain-link fence panel. |
Crushform.Impact.Prop.Debris | A debris piece of a breakable prop hits something. |
Crushform.Impact.Prop.Debris.Wood | A wooden debris piece lands. |
Crushform.Impact.Prop.Debris.Metal | A metal debris piece lands. |
Crushform.Impact.Glass.Crack | A glass pane cracks. |
Crushform.Impact.Glass.Break | A glass pane breaks and falls apart. |
Crushform.Impact.Glass.Shard | A glass shard hits something. |
Crushform.Impact.Tree.Hit | A body pushes a breakable tree. |
Crushform.Impact.Tree.Break | A breakable tree snaps and starts to fall. |
Crushform.Impact.Tree.Bend | A breakable pole gives way and stays leaning. |
Crushform.Impact.Tree.Land | A fallen tree trunk hits the ground. |
Crushform.Impact.Part.Hit | A vehicle’s part that swings on its hinge, or came off, hits something. |
Crushform.Impact.Part.Slam | A vehicle’s part swinging on its hinge slams into the closed end of its travel. |
Crushform.Impact.Part.Slam.Open | A vehicle’s part swinging on its hinge, flung wide, slams into the open end of its travel. |
The set’s row for a tag is a FCFImpactFeedbackEntry. Its Sounds are a list, one of which plays at random, so you need no sound cue for variation. Its Effect is a Niagara system that receives the float parameter Intensity. Its Attenuation shapes the sound over distance.
Set it up
Section titled “Set it up”This uses the shipped set, and then makes a row of your own.
- In the Content Browser, the default set is in Plugins › Crushform Content › Impact.
- Open
DA_CF_ImpactFeedback. Its Entries list has one row per tag. Find the row forCrushform.Impact.Prop.Break.Woodto see what a row holds: Sounds, Effect, Attenuation, the volume and pitch ranges, and the filters.
| Impact | ||
|---|---|---|
| Entries | 18 Array elements | |
| Index [ 0 ] | ||
| Index [ 1 ] | ||
| Index [ 2 ] | ||
| Index [ 3 ] | ||
| Index [ 4 ] | ||
| Index [ 5 ] | ||
| Index [ 6 ] | ||
| Index [ 7 ] | ||
| Index [ 8 ] | ||
| Index [ 9 ] | ||
| Index [ 10 ] | ||
| Index [ 11 ] | ||
| Event Tag | Crushform.Impact.Prop.Break.Wood | |
| Sounds | 5 Array elements | |
| Effect | NS_CF_ImpactWood_Break | |
| Attenuation | SA_CF_CarImpact | |
| Volume by Intensity | 0.41.0 | |
| Pitch Range | 0.921.08 | |
| Min Intensity | ||
| Cooldown Seconds | 0.1 | |
| Max Concurrent Voices | 4 | |
| Surface Overrides | 0 Array element | |
| Index [ 12 ] | ||
| Index [ 13 ] | ||
| Index [ 14 ] | ||
| Index [ 15 ] | ||
| Index [ 16 ] | ||
| Index [ 17 ] | ||
- To make your own set, choose Add › Miscellaneous › Data Asset, pick the class CFImpact Feedback Set, and add a row to Entries. Set its Event Tag to the tag, and fill in its sounds and effect.
- Open Project Settings › Plugins › Crushform Impact Feedback. Set Default Set to your set. A set only needs the rows for the tags you want to hear. A tag without a row uses its closest parent’s, so a row for
Crushform.Impactcovers every tag that has none of its own. - To give a vehicle its impacts, keep the adapter’s Impact Feedback on, which it is by default. Its
CF_ImpactFeedbackplays the adapter’s Impact Event Tag.CF_PartImpactFeedbackkeeps its own tags, and the adapter creates it only with Dirt and Dents on as well. The component table is in Core concepts.
Use it
Section titled “Use it”In your own project, a Blueprint plays an impact with the Play Impact node. It takes the tag, the location, the normal (up by default), the intensity from 0 to 1, the surface and an optional source. Impacts from one source share a cooldown. The graph below plays a tree-break impact at the actor’s location when a custom event fires.
Play Impact plays on the machine that calls it only, and on a dedicated server not at all. A game that wants every player to hear it calls it on every machine, for example from a multicast event.
The same in C++ uses the library function, with the tags in CFImpactTags. The block needs the CrushformImpact module in your Build.cs; the module list is in Installation.
#include "CFImpactFeedbackLibrary.h"#include "CFImpactTags.h"
void PlayTreeBreakHere(const UObject* WorldContext, const FVector& Location){ UCFImpactFeedbackLibrary::PlayImpact(WorldContext, CFImpactTags::Impact_Tree_Break, Location);}The signature is static void PlayImpact(const UObject* WorldContextObject, FGameplayTag Tag, FVector Location, FVector Normal = FVector::UpVector, float Intensity = 1.f, EPhysicalSurface Surface = SurfaceType_Default, const UObject* Source = nullptr). UCFImpactFeedbackSubsystem::Get(WorldContext)->PlayImpact(FCFImpactEvent) is the same call one level down, for code that builds the event itself.
Key settings
Section titled “Key settings”The project settings are on UCFImpactFeedbackSettings. The row and the components have their own values, which are listed below. The defaults are the plugin’s.
| Property | What it does | Default |
|---|---|---|
UCFImpactFeedbackSettings::DefaultSet | The impact set that plays. | /Crushform/Impact/DA_CF_ImpactFeedback |
UCFImpactFeedbackSettings::MaxAudibleDistanceCm | Beyond this distance, in cm, a sound is not played. | 6000 |
UCFImpactFeedbackSettings::MaxEffectDistanceCm | Beyond this distance, in cm, an effect is not spawned. | 8000 |
UCFImpactFeedbackSettings::MinVoiceSeconds | The shortest time a played sound holds a voice slot. | 0.25 |
UCFImpactFeedbackSettings::MaxVoiceSeconds | The longest time a played sound holds a voice slot. | 3 |
UCFImpactFeedbackSettings::MaxSoundsPerFrame | The most sounds that start in one frame. The rest wait, strongest first, for later frames. 0 turns the cap off. | 2 |
UCFImpactFeedbackSettings::SoundQueueSeconds | How long a sound over the frame’s cap may wait; past it, the sound is dropped. | 0.15 |
UCFImpactFeedbackSettings::IgnoredHitActorClasses | A hit by an actor of one of these classes is no impact. | empty |
UCFImpactFeedbackSettings::bUseDefaultBreakableHost | Whether the plugin maps breakable feedback to impact events. | true |
FCFImpactFeedbackEntry::VolumeByIntensity | The volume multiplier at intensity 0 and at intensity 1. | (0.4, 1.0) |
FCFImpactFeedbackEntry::PitchRange | The random pitch multiplier range. | (0.92, 1.08) |
FCFImpactFeedbackEntry::MinIntensity | An intensity below this plays nothing. 0 turns the filter off. | 0 |
FCFImpactFeedbackEntry::CooldownSeconds | The time between two impacts of one source. | 0.1 |
FCFImpactFeedbackEntry::MaxConcurrentVoices | The most sounds of the row that play at once. | 4 |
UCFImpactFeedbackComponent::ImpulsePerKgForFullIntensity | The impulse per kilogram that plays at full strength. | 600 |
UCFImpactFeedbackComponent::MinImpulsePerKg | The impulse per kilogram below which a hit is silent. | 50 |
UCFImpactFeedbackComponent::ContactGapSeconds | The silence after which the next hit from a component is a new contact. | 0.1 |
UCFImpactFeedbackComponent::ContactSpikeRatio | Within a contact, a hit plays only if its impulse is this many times the running impulse. | 2 |
UCFNetImpactFeedbackComponent::MinRelayIntervalSeconds | The shortest gap between two impacts this body sends to other players, except for a markedly stronger hit, which is sent sooner. | 0.5 |
UCFPartImpactFeedbackComponent::OpenSlamEventTag | The impact event of a slam into the open end of the part’s travel. Empty: no sound there. | Crushform.Impact.Part.Slam.Open |
UCFPartImpactFeedbackComponent::SlamSpeedForFullIntensity | The speed, in cm/s, of a part’s slam at full strength. | 500 |
UCFPartImpactFeedbackComponent::MinSlamSpeed | The speed, in cm/s, below which a slam is silent. | 40 |
Check that it works
Section titled “Check that it works”In any build except Shipping, open the console with the tilde key.
crushform.Impact.LogHits 1turns on the markers. Drive the sedan into a wall, a fence or a tree. Each judged hit leaves a marker for about 5 seconds: green for a contact impact that plays, yellow for a hit within a steady contact, and red for a hit below the minimum. Usecrushform.Impact.LogHits 0to turn them off. It is0by default.stat CFImpactFeedbackshows the impact cycles.- Hit a wall with the car. You hear the sound and see the effect at the contact.
Troubleshooting
Section titled “Troubleshooting”Nothing plays on a dedicated server, or the other players hear nothing
Section titled “Nothing plays on a dedicated server, or the other players hear nothing”Cause. A dedicated server plays no impact at all. A Play Impact call plays on the machine that makes it only. Impacts from a component reach other players only through a UCFNetImpactFeedbackComponent, which relays them.
Fix. Call Play Impact on every machine that should hear it. For a body’s impacts that other players should hear, use UCFNetImpactFeedbackComponent on it.
A tag plays nothing
Section titled “A tag plays nothing”Cause. The active set has no row for the tag or for any of its parents, so UCFImpactFeedbackSet::FindEntry finds nothing. A component or adapter whose tag is cleared by hand also plays nothing.
Fix. Add a row for the tag to the set, or a row for its closest parent. Put back the tag on the component or the adapter, or leave it empty to play the plugin’s default.
A body I added a component to is silent
Section titled “A body I added a component to is silent”Cause. There are two cases. A UCFImpactFeedbackComponent observes no primitive until SetObservedPrimitive is called in C++, so a component added in Blueprint alone stays silent. A UCFNetImpactFeedbackComponent observes its owner’s root primitive, and if that root is not a primitive, it logs this line and stays silent:
%s: owner %s has no primitive root; its impacts stay silentFix. For the base component, give it the primitive from C++ with SetObservedPrimitive. For a body that should be heard by the other players, use UCFNetImpactFeedbackComponent, and make sure the owner’s root component is a primitive, such as the body’s mesh.
A hit is silent, or plays only the effect
Section titled “A hit is silent, or plays only the effect”Cause. The hit is below Min Impulse Per Kg (50) or below the row’s Min Intensity, so it is silent. Or the row’s Max Concurrent Voices are all busy, so the impact plays its effect with no sound.
Fix. Lower Min Impulse Per Kg or Min Intensity for the row, or raise Max Concurrent Voices. Turn on crushform.Impact.LogHits 1 to see whether a hit reads red (below the minimum) or was judged at all.
A steady contact plays the impact again and again
Section titled “A steady contact plays the impact again and again”Cause. The component plays a new impact only when a hit is a spike within its contact: its impulse is at least Contact Spike Ratio (2) times the running impulse. A contact that keeps its impulse does not repeat. A contact that breaks for longer than Contact Gap Seconds (0.1 s) counts as a new one.
Fix. Raise Contact Gap Seconds above a few physics steps if a single impact splits into several. Keep the spike ratio at its default, unless a steady contact still repeats.
For the breaks that these hits come from, see Fences and props and Breakable trees and poles. The vehicle’s own sounds of impact are on its adapter, described in Core concepts.