USW projects

2. Stop location prediction

You don’t really need iterative method to predict stop location.
If ground friction is zero, solving simple kinematic equation is enough: d = (Vf^2 - Vi^2) / 2a where Vf - final velocity - BRAKE_TO_STOP_VELOCITY, Vi - initial velocity, a= - braking deceleration
With ground friction, you need to integrate V/a(V)dV where a(V) = V*Fr + BD where Fr - ground friction, BD - braking deceleration

Note that internally Epic uses BRAKE_TO_STOP_VELOCITY on character movement component so use this as final velocity and not zero. Otherwise location prediction will be a bit off.

Sample code:



float Friction = GetCharacterMovement()->GroundFriction * GetCharacterMovement()->BrakingFrictionFactor;
float BrakingDeceleration = GetCharacterMovement()->BrakingDecelerationWalking;
FVector Velocity = GetVelocity();
StopLocation = GetActorLocation();

if (Friction == 0.f)
{
    // No friction - simple kinematic equation
    float Distance = (Velocity.SizeSquared() - UCharacterMovementComponent::BRAKE_TO_STOP_VELOCITY * UCharacterMovementComponent::BRAKE_TO_STOP_VELOCITY) / (2.f * BrakingDeceleration);
    StopLocation += Velocity.GetSafeNormal() * Distance;
}
else
{
    // Integrate
    float Distance = BrakingDeceleration * FMath::Loge(BrakingDeceleration + UCharacterMovementComponent::BRAKE_TO_STOP_VELOCITY * Friction) / (Friction * Friction) - (UCharacterMovementComponent::BRAKE_TO_STOP_VELOCITY / Friction);
    Distance -= BrakingDeceleration * FMath::Loge(BrakingDeceleration + Velocity.Size() * Friction) / (Friction * Friction) - (Velocity.Size() / Friction);
    StopLocation += Velocity.GetSafeNormal() * Distance;
}


1 Like