Situational walking friction

I’m working on a movement system and trying to create an effect where you can change velocity on a line parallel to your current speed vector almost instantly, but where acceleration that is perpendicular to your current heading is dampened.
In practice, this would mean strafing back and forth would have an ‘arcade’ feel, but trying to strafe while already moving forwards/backwards would give a slower and more momentum-based velocity change. If you’re already moving forward and do a 90 degree turn, the same momentum behavior should be present(so you’d get a more rounded turn, rather than sharp).

This is not compatible with UE’s existing acceleration/friction system; if you do low friction/acc you get the momentum feel and if you do high friction/acc you get snappy. I’m essentially looking for low-friction acceleration perpendicular to velocity direction, and high-friction acceleration parallel to velocity direction.

I’ve been trying an approach where I split the acceleration vector into components parallel and perpendicular to the velocity vector, dampening the perpendicular part and then putting them back together:


const float AccelSize = Acceleration.Size();
const FVector AccelDir = Acceleration.GetSafeNormal();
const FVector VelDir = Velocity.GetSafeNormal();

const FVector AccDirParallelToVelocity = AccelDir.ProjectOnTo(VelDir);
const FVector AccDirPerpendicularToVelocity = AccelDir - AccDirParallelToVelocity;

FVector NewAccDir = (AccDirParallelToVelocity + AccDirPerpendicularToVelocity * FMath::Min(DeltaTime * Friction, 1.f));
NewAccDir.Normalize();
Acceleration = NewAccDir * AccelSize;

It gives the effect I’m after in many cases, but creates problems when frequently changing direction, where you’re suddenly accelerating in a slightly “wrong” direction for an extended period of time. Guess I should have expected that.

Any idea for a fix, or new ideas for solving the problem another way?

Something I always meant to have a look at, but never got around too.

My thought was cache previous velocities, dampening them all based on how parallel they were to the current desired direction of movement.
As each previous velocity approaches zero, remove them from the cached list.
Or something.

Again, its something I haven’t actually done yet :expressionless: