“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?