Physics Constraint Component
The child is
Component/Bone 1and the parent isComponent/Bone 2!!
Stability
To have a stable chain of physics constraints (eg: multiple capsules forming a cable) you should have everything parent correctly.
For example, if you have a cable, a player capsule and a static cube, the chain should be Cube -> Cable Capsule -> ... -> Cable Capsule -> Player Capsule as Parent -> Child.
Adriel
“The solver will iterate trying to solve the chain, then after that it’ll do the projection step to pull every child towards its parent. You want everything pulled towards the solved state which is a chain of things from the cube to the player”
You can (and should) try to bump the number in the physics solver settings (in Project Settings).

Breaking
Before calling OnConstraintBroken inside UPhysicsConstraintComponent::OnConstraintBrokenWrapper (there is also UPhysicsConstraintComponent::OnConstraintBrokenHandler) the breaking state is pulled in FPhysicsSolverBase::PullPhysicsStateForEachDirtyProxy_External in a loop iterating LatestData->DirtyJointConstraints and calling FJointConstraintPhysicsProxy::PullFromPhysicsState on each entry.
Inside FPhysScene_Chaos::OnSyncBodies, if the bIsBreaking in FJointConstraint, FOutputData is true the FConstraintBrokenDelegateWrapper wrapper will be called (see OnConstraintBrokenWrapper above).
About
bIsBrokenin OutputDataIt reflects if
IsConstraintEnabledreturn false (bIsBroken = !IsConstraintEnabled)
This output data is pulled and set in FJointConstraintPhysicsProxy::PullFromPhysicsState (see above) by reading the buffer FDirtyJointConstraintData.
The actual set of bIsBreaking (and the rest of the FDirtyJointConstraintData Buffer) is inside FJointConstraintPhysicsProxy::BufferPhysicsResults where it calls IsConstraintBreaking on a FPBDJointConstraintHandle (FPhysScene_Chaos::OnSyncBodies).
This calls FPBDJointConstraints::IsConstraintBreaking on a FConstraintContainer (templated to FPBDJointConstraints for FPBDJointConstraintHandle), which just reads the value of bBreaking on the element stored in ConstraintStates.
This bBreaking state is set by FPBDJointConstraints::SetConstraintBroken (only called by FPBDJointConstraints::BreakConstraint (by the way this also disables the constraint) and FixConstraint).
The only usage of this break function is FPBDJointConstraints::SetSolverResults which is called in Chaos::Private::ScatterOutputImpl (called by FPBDJointContainerSolver::ScatterOutput).
This function will set the value of the argument bIsBroken by calling IsBroken() on the solver (templated to FPBDJointCachedSolver here). This function just returns the value of the variable bIsBroken of the cached solver.
This variable is only set by SetIsBroken() which is only called in Chaos::Private::ApplyPositionConstraintsImpl (called by FPBDJointContainerSolver::ApplyPositionConstraints, search for Solver.SetIsBroken).
This Solver.SetIsBroken call occurs because GetJointShouldBreak returned true.
Since GetJointShouldBreak is called on a FPBDJointCachedSolver its doing some math to get the linear and angular impulse so you can’t simply read some variables to get the values.
Debug values of
LinearImpulseandAngularImpulseinGetJointShouldBreak(Example for
LinearImpulse)
- Add a conditional breakpoint by using
LinearForceSq > LinearThresholdSqat the last line of the first if block- To get the value of
LinearForceSqrun the following(LinearImpulse.X*LinearImpulse.X + LinearImpulse.Y*LinearImpulse.Y + LinearImpulse.Z*LinearImpulse.Z) / (Dt * Dt * Dt * Dt). This mimics the math used to getLinearForceSq.
Motor
Orientation, Position and Velocity Target of the motors are relative to the constraint origin.
Constraint on body instance
See Constraint
Commands & debug
Some interesting commands, a lot more available
Stat ChaosConstraintSolverStat ChaosConstraintDetails
See Console commands & debugging in /Physics for more Chaos commands
