DAMAGEDAMAGE ZONES AND EVENTS
Damage zones and events
What it does
Section titled “What it does”Damage zones tell your game how dented each side of a body is. A body has six sides: front, back, left, right, top and bottom. Each side reports its deepest dent and its average dent, from 0 for an untouched body to 1 for a body dented as far as it allows. The event On Damage Changed fires when any side changes, so your game can react to the damage: a warning light, a lower top speed, a score.
How it works
Section titled “How it works”The six sides. Each side is the outer third of the body along one axis of its root. The front is +X of the root, the back is -X, the left is -Y, the right is +Y, the top is +Z and the bottom is -Z. Neighbouring sides overlap at the edges, so a dent near a corner counts for both sides.
Max and Mean. For each side, Max is the deepest dent on it: the largest displacement of a lattice node, divided by the profile’s Max Displacement, clamped to 1. Mean is the average of the same value over the nodes of that side. Both run from 0 to 1.
Any box. GetDamageInBox gives the same two values for a box you choose, such as the area around a headlight. The box is in the root’s space, the same space as a glass pane’s Crush Link Box.
Confirmed damage only. The zones read the damage the server has confirmed. On a client, a hit you predict is not in the zones until the server confirms it. So the event reports the same numbers on every machine, and a hit the server rejects never shows.
When the event fires. The event checks at most once a frame, after the body’s lattice changed. It fires only when the zones differ from what it last reported. It fires on every machine, including a dedicated server. A repair fires it with zeros. A player who joins late gets it once the replicated damage has built the lattice on their machine.
What it needs. The vehicle’s adapter needs Dirt and Dents on, and the profile needs Dents on. Without them the zones read zero and the event never fires. The adapter forwards the event and both getters, so you can bind to the vehicle’s adapter without finding the deform component.
Damage zones are not the same thing as stiffness zones. Stiffness zones are boxes that make part of the body stiffer or softer, and Crushform.ShowZones draws those. Damage zones only report the damage that has happened. See Soft zones for the stiffness zones.
Set it up
Section titled “Set it up”- Open your vehicle’s Blueprint, for example a copy of
BP_VehicleAdvSedan. Select its Crushform Chaos Vehicle Adapter component. Make sure Dirt and Dents is on. Put a second copy of the vehicle on the level for the check below, away from the car you drive. - Open the vehicle’s deform profile and make sure Dents is on. See Dents and the lattice.
- Nothing else needs creating. The zones come from the lattice of the body. The next section shows how to read them.
Use it
Section titled “Use it”In Blueprint, bind On Damage Changed on the vehicle’s adapter. The event passes the six sides as Zones. Break Zones to get Front, break Front to get its Max, and print it. The same pins give the other sides, and Mean in place of Max.
The graph prints the front side’s Max each time the event fires. It prints a bare number, with no label: the value alone, without the name of the side. The event also reaches every other side through the same pins.
From C++, bind a lambda to the deform component’s native event, and read a box in the same way. The native event fires just before the Blueprint one, with the same zones. The body collision follows the same dents.
#include "CFDamageTypes.h"#include "CFDeformComponent.h"
Deform->OnDamageChangedNative.AddLambda([](const FCFDamageZones& Zones){ UE_LOG(LogTemp, Log, TEXT("Front max %.2f"), Zones.Front.Max);});
const FCFDamageValues Nose = Deform->GetDamageInBox(NoseBox); // NoseBox: an FBox in the owner's root spaceDeform is the body’s UCFDeformComponent. NoseBox is an FBox in the root’s space.
Key settings
Section titled “Key settings”| Property | What it does | Default |
|---|---|---|
UCFVehicleAdapterComponent::bDirtAndDents | Turns the damage on for the vehicle. Off: the zones read zero and the event never fires. | On |
UCFProfile::bDents | Whether hits and presses dent the body. Off: the zones never change. | On |
UCFProfile::MaxDisplacement | The displacement, in cm, that counts as a full dent. Max and Mean divide by it. | 60 |
No other setting changes the zones. The values come from the lattice of the body.
Check that it works
Section titled “Check that it works”In any build except Shipping, play in the editor. Crushform.DebugImpact never hits the car you drive, because the trace skips it. So use the second copy with the graph, parked away from your own car. Drive up to it from the front and run Crushform.DebugImpact 10 <name>, with part of your copy’s name as the World Outliner shows it in place of <name>. The hit goes to the point of that car’s body nearest its middle, seen from where you stand, so from the front it lands on the front. The event fires, and the graph prints the front side’s Max. A hit on the front should print a value above zero.
To check the back side, change the graph’s break to read Back instead of Front, then approach the copy from its back and hit it the same way. Run Crushform.RepairAll: every side returns to zero, and the event fires once with zeros.
From C++ on the authority, CFScriptedHits::ApplyScatteredHits applies a number of hits at random points of a body. The debug mode presets use it.
Troubleshooting
Section titled “Troubleshooting”- On Damage Changed never fires. Dirt and Dents is off on the vehicle’s adapter, or Dents is off in the profile, or the body has no profile. Turn the switches on and assign a profile.
- The zones read zero right after you hit the car. On a client, your own hit is only a prediction until the server confirms it, and the zones count only confirmed damage. Wait a moment for the server’s answer, or read the zones on the server.
- A box reads zero over a visible dent. The box is not in the root’s space, or it lies outside the body’s lattice, or it is unset. Build the box in the owner’s root space, the same space as the root’s axes.
- The front and the back look swapped. The sides follow the axes of the root component, with +X as the front. A car whose mesh faces another way needs its root turned to match. Check the root’s rotation.