WORLDBREAKABLE TREES AND POLES
Breakable trees and poles
What it does
Section titled “What it does”A breakable tree is a trunk that a car can knock over. Drive into a tree and it bends. Push it past its yield angle and it either falls and lies where it came down, or, for a pole, bends and stays leaning. After a while it stands up again.
How it works
Section titled “How it works”A tree is an ACFBreakableTree actor. It has one physics body, the trunk, and one joint that holds the trunk to the ground. The joint holds the trunk with a drive spring and, for a pole, a hard stop. Until a vehicle comes close, the trunk stays dormant and costs nothing: a level full of trees is cheap while the cars are far away.
- Armed. A vehicle with a
CF_PropContactcomponent arms the trees around it. The trunk starts to simulate and the joint is created. A body that is asleep and slower thanUCFPropContactComponent::TreeArmMinSpeedCmS(5 cm/s by default) arms nothing, so its trees rest. An unarmed tree is a kinematic wall that still blocks the car. - Yielded. When the trunk leans past
UCFTreeConfig::YieldAngleDegrees(15 degrees), it yields. What happens next depends on the species’ Yield Mode:- Fell and Fall (
FellAndFall): the joint releases atReleaseAngleDegrees(65 degrees) and the trunk falls free. - Bend and Lock (
BendAndLock): the trunk stops atStopAngleDegrees(45 degrees) and keeps its lean. A pole is this kind.
- Fell and Fall (
- Landed. A released trunk that hits the ground at
LandMinDeltaVCmS(80 cm/s) or more counts as landing. - Settled. The trunk freezes into static geometry where it lies.
- Respawned. After
RespawnDelaySeconds(300 s by default) the tree stands again, sinking in overRespawnSinkSeconds(3 s). It waits until no player is withinRespawnClearRadiusCm(4000 cm), no body ofRespawnBlockingObjectTypesstands on its spot, and, whenbRespawnOnlyWhenUnseenis on, no camera looks at it.
A fallen trunk blocks vehicles for VehiclePassThroughDelaySeconds (1 s), then the cars drive through it, unless bFallenTrunkCollidesWithVehicles is on. The tree’s hit, yield, landing, settle and respawn events fire on every machine, from what each machine sees. A player who joins later is not told about an event that already happened.
| Crushform | ||
|---|---|---|
| Tree | ||
| Trunk Mesh | TrunkMesh | |
| Trunk Skinned Mesh | TrunkSkinnedMesh | |
| Trunk Constraint | TrunkConstraint | |
| Tree Config | DA_CF_Tree | |
The tree’s Tree Config data asset holds the species. A tree with no config, or with a config that fails its checks, refuses to arm.
Set it up
Section titled “Set it up”This uses the shipped trees on the Proving Ground. To make your own species, see step 3.
- In the Content Browser, the shipped trees are in Plugins › Crushform Content › Trees.
- Drag
BP_CF_Tree(a fell-and-fall tree) orBP_CF_Pole(a bend-and-lock pole) into your level. Both are placed actors with a Tree Config set to the data asset of their species,DA_CF_TreeorDA_CF_Pole. - For your own species, in the Content Browser choose Add › Miscellaneous › Data Asset, pick the class CFTree Config and name it. Set Mass Kg, Yield Mode and the angles as in the key settings table below.
| Crushform | ||
|---|---|---|
| Tree | ||
| Mass Kg | 900.0 | |
| Yield Mode | ||
| Yield | ||
| Yield Angle Degrees | 15.0 | |
| Felling | ||
| Felling Drive Fade Seconds | 0.01 | |
| Felling Damping Strength | 50000000.0 | |
| Release Angle Degrees | 65.0 | |
| Vehicle Pass Through Delay Seconds | 1.0 | |
| Stop Angle Degrees | 45.0 | |
| Bend and Lock Lock Strength Multiplier | 100.0 | |
- Select the tree in the level. In the Details panel, under Crushform › Tree, set Tree Config to your data asset.
- Make sure the vehicle that should fell the tree has its adapter’s Breaks Props on, which it is by default. The adapter then creates the
CF_PropContactcomponent.
Use it
Section titled “Use it”In your own project, a Blueprint can react to a tree. The graph binds a handler to On Yielded when the tree begins to play. The handler prints a message each time the tree yields.
The same in C++ uses the native delegates. Each event has a ...Native twin that a C++ listener can add to:
#include "CFBreakableTree.h"
void ListenToTree(ACFBreakableTree* Tree){ if (IsValid(Tree)) { Tree->OnYieldedNative.AddLambda([](ACFBreakableTree& Yielded, bool bPredicted) { UE_LOG(LogTemp, Log, TEXT("%s yielded, predicted: %d"), *Yielded.GetName(), bPredicted); }); }}The C++ block needs the CrushformBreakable module in your Build.cs. The module list is in Installation. The header declares FCFOnTreeYieldedDelegate OnYieldedNative as ACFBreakableTree& Tree, bool bPredicted. The state queries are IsArmed(), IsYielded(), IsSettled(), GetRespawnCount() and GetDeflectionDegrees(), all const.
Key settings
Section titled “Key settings”The species settings are on UCFTreeConfig. In its Details panel they sit under Crushform › Tree, in the sub-groups Yield, Felling, Drive, Vehicles, Events, Feedback and Respawn. The defaults are the plugin’s, so a new config starts with them.
| Property | What it does | Default |
|---|---|---|
UCFTreeConfig::MassKg | The trunk’s mass. The main lever for how a vehicle feels when it pushes. | 900 |
UCFTreeConfig::YieldMode | FellAndFall drops the trunk. BendAndLock stops it at its stop angle and keeps it leaning. | FellAndFall |
UCFTreeConfig::YieldAngleDegrees | The lean, in degrees, past which the tree yields. | 15 |
UCFTreeConfig::ReleaseAngleDegrees | Fell and fall only: the lean at which the joint releases. | 65 |
UCFTreeConfig::StopAngleDegrees | Bend and lock only: the stop the pole bends to. | 45 |
UCFTreeConfig::DrivePositionStrength | The spring that holds the trunk upright inside its cone. It must not be zero. | 5.0e8 |
UCFTreeConfig::bFallenTrunkCollidesWithVehicles | Whether a fallen trunk keeps blocking vehicles. Off lets them through after the pass-through delay. | false |
UCFTreeConfig::VehiclePassThroughDelaySeconds | Fell and fall only: how long a falling trunk still blocks vehicles. | 1 |
UCFTreeConfig::HitMinDeltaVCmS | The smallest change of speed, in cm/s, that counts as a hit. | 30 |
UCFTreeConfig::RespawnDelaySeconds | How long a felled or bent tree stays down. 0 means it never comes back. | 300 |
UCFTreeConfig::RespawnClearRadiusCm | No respawn while a player is this close, in cm. | 4000 |
UCFTreeConfig::RespawnBlockingObjectTypes | Bodies of these object types on the tree’s spot keep it down. | ECC_Vehicle, ECC_Pawn, ECC_PhysicsBody |
UCFTreeConfig::bRespawnOnlyWhenUnseen | No respawn while a player’s camera looks at the tree. | true |
UCFTreeConfig::HitFeedbackTag | The impact tag a hit plays. Empty plays the plugin’s Crushform.Impact.Tree.Hit. | empty |
UCFTreeConfig::YieldFeedbackTag | The impact tag of the yield. Empty plays the plugin’s Crushform.Impact.Tree.Break or Crushform.Impact.Tree.Bend. | empty |
UCFTreeConfig::LandFeedbackTag | The impact tag of the landing. Empty plays the plugin’s Crushform.Impact.Tree.Land. | empty |
UCFBreakableSettings::TreeCollisionProfile | The collision profile of the trunk. Vehicles must block it. | None (uses Destructible) |
UCFBreakableSettings::TreeWheelTraceChannel | The channel the vehicle wheels trace the ground on. | ECC_WorldDynamic |
UCFBreakableSettings::RespawnCheckIntervalSeconds | How often a yielded tree checks whether it may respawn, in seconds. | 5 |
The project settings are under Project Settings › Plugins › Crushform Breakable, in the Trees and Respawn groups.
Check that it works
Section titled “Check that it works”In any build except Shipping, open the console with the tilde key.
stat CrushformBreakableshows the Breakable Tree Tick and Breakable Tree Trunk Hit cycles. They move while a car is near a tree.- Drive a car into
BP_CF_Tree. The trunk bends, passes its yield angle and falls. Drive intoBP_CF_Pole: it bends and stays leaning. - For a quick respawn check, set
RespawnDelaySecondson your config to a few seconds. The tree stands again once no player is within its clear radius and no camera sees it.
If a tree stays standing when the car hits it, see the first entry under Troubleshooting, below.
Troubleshooting
Section titled “Troubleshooting”The tree never bends
Section titled “The tree never bends”Cause. The tree has no Tree Config, or its config fails its checks. The tree then refuses to arm and logs one line, once:
Tree %s has no TreeConfig assigned, refusing to armor, for a config that fails UCFTreeConfig::ValidateTreeConfig:
Tree %s has an invalid TreeConfig (%s), refusing to armFix. Set Tree Config on the tree in the level. If the second line appears, its text names the broken value. Fix it in the data asset and run the level again.
The car stops at the tree and the tree never bends
Section titled “The car stops at the tree and the tree never bends”Cause. The vehicle has no CF_PropContact component, because Breaks Props is off in its adapter. Nothing arms the tree, so it stays a kinematic wall that stops the car. The contact component arms a tree only while its body is awake or moving faster than TreeArmMinSpeedCmS (5 cm/s by default).
Fix. Turn Breaks Props on in the vehicle’s adapter. The adapter then creates CF_PropContact, which arms the trees the car approaches.
A fallen trunk blocks the car, or a tree never comes back
Section titled “A fallen trunk blocks the car, or a tree never comes back”Cause. A fallen trunk blocks vehicles while bFallenTrunkCollidesWithVehicles is on, and for VehiclePassThroughDelaySeconds after a fell-and-fall yield. A tree with RespawnDelaySeconds at 0 never respawns. A tree respawns only when no player is within its clear radius, no object of its blocking types stands on its spot, and, with bRespawnOnlyWhenUnseen on, no camera looks at it.
Fix. Set bFallenTrunkCollidesWithVehicles off to let cars pass through the trunk once the delay passes. For a respawn, set RespawnDelaySeconds above zero, and move the player or the blocking object away from the tree’s spot.
The trunk acts like a wall
Section titled “The trunk acts like a wall”Cause. UCFTreeConfig::DrivePositionStrength is too stiff. The config’s comments say a drive that is too strong makes the trunk an immovable wall that no vehicle can beat. DriveVelocityStrength is meant to stay at about a tenth of it.
Fix. Lower DrivePositionStrength and keep DriveVelocityStrength at about a tenth of it. Then push the tree in the level and check that it still stands on its own.
For the other world systems, see Fences and props and Impact feedback.