Good questions, that is a complicated line of code Hopefully I can clarify:
Basically the code in question applies some extra force to change the direction in line with acceleration, but never increases the magnitude.
First off, ControlAcceleration is clamped to a max magnitude of 1.0 right above, so ControlAcceleration * Velocity.Size() will never exceed the Velocity magnitude.
const FVector ControlAcceleration = GetPendingInputVector().GetClampedToMaxSize(1.f);
The hardcoded “8.f” is the “ability to change”, with higher values increasing the rate of change. It really should be a variable and not hard-coded, I will change that. Clamping to a max of 1.0 just keeps us from exceeding the initial magnitude.
It might be easier to parse if written like so (which is equivalent, but has more operations):
float dt = FMath::Min(DeltaTime * 8.f, 1.f); // never above 1
Velocity = Velocity - (Velocity * dt) + (ControlAcceleration * Velocity.Size() * dt);
If you draw out some simple vectors using this form, it might be easier to understand. You take the Velocity vector, pull back a bit (potentially all the way to a velocity of zero). From there you add a vector in the direction of acceleration by the same amount you pulled back.
Consider the simplest case, which is that ControlAcceleration and Velocity point in the same direction. In that case Velocity - ControlAcceleration * Velocity.Size() equals 0, and Velocity doesn’t change at all. In the case that ControlAcceleration is exactly opposite the current direction, the change is scaled by time and the constant factor, but never allowed to exceed the current magnitude. In the case that you are moving forward and strafe right or left, you get a lateral change equal to the final term above. If “dt” was really high, you just set your velocity in the exact direction of acceleration, with current velocity magnitude.
Again it’s essential to note that we never increase the magnitude using this approach.
Without this code (essentially changing that 8.f to zero), you just change velocity with the later code that applies acceleration to velocity. If you try that you’ll feel like you are drifting a lot, and changes in direction are slow, more like you are floating in space and applying a thruster. However if you want it like that, then you’d set this turning force to zero (which will be easier once I expose it as a variable).
For reference this is also almost identical to the code in UCharacterMovementComponent::CalcVelocity():
// Friction affects our ability to change direction. This is only done for input acceleration, not path following.
const FVector AccelDir = GetSafeNormalPrecise(Acceleration);
const float VelSize = Velocity.Size();
Velocity = Velocity - (Velocity - AccelDir * VelSize) * FMath::Min(DeltaTime * Friction, 1.f);
We use the Friction setting there as an indicator of your ability to change direction.