# About UCharacterMovementComponent 1% error tolerance

“UCharacterMovementComponent::CalcVelocity” has code for over max speed and need to slow down to it.

``````const bool bVelocityOverMax = IsExceedingMaxSpeed(MaxSpeed);

// Only apply braking if there is no acceleration, or we are over our max speed and need to slow down to it.
if ((bZeroAcceleration && bZeroRequestedAcceleration) || bVelocityOverMax)
{
const FVector OldVelocity = Velocity;

const float ActualBrakingFriction = (bUseSeparateBrakingFriction ? BrakingFriction : Friction);
ApplyVelocityBraking(DeltaTime, ActualBrakingFriction, BrakingDeceleration);

// Don't allow braking to lower us below max speed if we started above it.
if (bVelocityOverMax && Velocity.SizeSquared() < FMath::Square(MaxSpeed) && FVector::DotProduct(Acceleration, OldVelocity) > 0.0f)
{
Velocity = OldVelocity.GetSafeNormal() * MaxSpeed;
}
}
``````

It use IsExceedingMaxSpeed:

``````bool UMovementComponent::IsExceedingMaxSpeed(float MaxSpeed) const
{
MaxSpeed = FMath::Max(0.f, MaxSpeed);
const float MaxSpeedSquared = FMath::Square(MaxSpeed);

// Allow 1% error tolerance, to account for numeric imprecision.
const float OverVelocityPercent = 1.01f;
return (Velocity.SizeSquared() > MaxSpeedSquared * OverVelocityPercent);
}
``````

It square first，then Multiply 1.01f.

And “UCharacterMovementComponent::ApplyVelocityBraking” possible set Velocity = FVector::ZeroVector.

And “UCharacterMovementComponent::ApplyRequestedMove” use Multiply 1.01f first, then square:

``````const float CurrentSpeedSq = Velocity.SizeSquared();
if (bRequestedMoveUseAcceleration && CurrentSpeedSq < FMath::Square(RequestedSpeed * 1.01f))
{
// Turn in the same manner as with input acceleration.
const float VelSize = FMath::Sqrt(CurrentSpeedSq);
Velocity = Velocity - (Velocity - RequestedMoveDir * VelSize) * FMath::Min(DeltaTime * Friction, 1.f);

// How much do we need to accelerate to get to the new velocity?
NewAcceleration = ((MoveVelocity - Velocity) / DeltaTime);
NewAcceleration = NewAcceleration.GetClampedToMaxSize(MaxAccel);
}
``````

This leads to inconsistent judgment on both sides. We all know (1.01)^2 > 1.01,so it may make “UCharacterMovementComponent::ApplyVelocityBraking” set Velocity = FVector::ZeroVector. And it happened in my work, I found UE4.5、 UE4.14、UE4.18 is same!

So, What is the reason for this design? Or this is a bug?