Add Movement Input does not need to be framerate independent?

Hi, I’d like to know why the mouse/gamepad input event value do not need to multiply world delta seconds for the Add Movement Input node to be framerate independent?
It is from the Unreal First person template blueprint.

I have tried setting different max FPS value to test it out but the movement speed seems not to be affected.

Adding movement input (axis with range [-1,1]) is not the same as adding movement based on location (eg SetActorLocation). For the latter you should use DeltaTime indeed to make it framerate independent.

The difference is where it’s being used.
The character movement component uses the movement input and direction to determine where the user wants to go.
The result is in the end internally multiplied by the delta seconds, which results in framerate independent movement. (See code in c++ for the CharacterMovementComponent).

Hope this clarifies things for you :slight_smile:

4 Likes

Adding to @AndreasV’s answer, conceptually “input” is not the same as “movement”.

Add Movement Input basically means “remember that the user wants to move forward”.

Then later, when we’re actually ready to move the pawn, THEN we’ll look at what direction the user intends to move, and apply acceleration and delta time to it to determine HOW MUCH it should move in that direction during the current frame.

For this reason most code will normalize the input vector, clamping at 1. By clamping it when you use it, you keep the user’s directional intent without giving them the ability to break your desired physics limitations.

Thus for input, only the direction is important, from 0-1 magnitude in that direction.

Consider:

FVector Input1 { 0.f, 0.f,   1.f };
FVector Input2 { 0.f, 0.f, 100.f };

FVector MoveTo1 = GetCurrentLocation() + Input1 * MaxSpeed * DeltaTime;
FVector MoveTo2 = GetCurrentLocation() + Input2 * MaxSpeed * DeltaTime;

In the above example, MoveTo1 is the location you want the object to end up if you’re limiting it to your MaxSpeed physics limit.

In contrast, MoveTo2 and its incorrect use of non-normalized Input2 will result in the object effectively having 100x more speed than you intended. It will zip around the screen much faster than you want it to.

To be safe and ensure that we don’t let the user break our physics, typically you’d do like:

FVector MoveTo3 = GetCurrentLocation() + Input2.GetSafeNormal() * MaxSpeed * DeltaTime;

Above, MoveTo3 will be valid, the same as MoveTo1, because it is normalizing Input2 to remove the extra magnitude and clamp it to 0-1.

2 Likes