Why is Actor Velocity only accurate when actor is selected in details?

UE5-0

Hello and thanks for reading.

I move an Actor every frame using AddMovementInput(GetActorForwardVector(), forwardSpeed);

When i move my character forward without deviation he hits a max velocity.X of ~416. His max should be 500.

image

When I select my character in the details panel while running the game, then click back into the game viewport and move my character forward they hit a max velocity.X of 500.

image

Y stays 0, Z stays 0. Nothing else changes except I can see my character in the details panel.

When I click another object in the details panel and click back into the viewport then move forward, the velocity.X goes back to the unexpected 416.

I’ve done various tests over the course of a few hours and I believe i have isolated it to the actor velocity only being accurate when the details of the actor in motion is visible. Otherwise the speed is for whatever reason limited.

Am I making an error? Is this expected somehow or a bug? Thank you

Consider to take the delta times into a count and multiply them with your input.
Frame based acceleration without using the delta time leads to different speed with different frames per second. When you do something else your fps change and your speed changes.

Selecting different things in the viewport change your speed. Possibly you also have vsync enabled which caps your input at 60 fps.

1 Like

Thank you for your response, i’m currently solving my forward speed like this:

AddMovementInput(GetActorForwardVector(), forwardSpeed * DeltaTime);

But now i’m thinking about maybe AddMovementInput does not expect the speed to be dilated by time. Maybe i need to remove the DeltaTime multiplier in this instance. Appreciate you responding i’ll look at the source code and see if i can reason out what is happening behind the scenes with AddMovementInput, thank you

From what i can see “AddMovementInput()” should take the normalized direction and then a scalarValue that is not tied to framerate. (i.e. scalarValue * DeltaTime seems to be the incorrect approach)

For others running into this problem, here is what AddMovementInput does from what i can tell:

  • AddMovementInput // multiplies the direction and scalar together and then stores it in the Pawn as “ControlInputVector”
  • UCharacterMovementComponent::TickComponent // consumes the input vector by calling ConsumeInputVector and stores the Vector in a local variable “InputVector” – seems to potentially toss this update away but generally continues
  • Retrieves Mesh and ticks it
  • Handles a networking, seems like prediction and correction code follows, but assuming you have greater authority than SimulatedProxy it continues here and eventually passes InputVector to the following function
void UCharacterMovementComponent::ControlledCharacterMove(const FVector& InputVector, float DeltaSeconds)
{
	{
		SCOPE_CYCLE_COUNTER(STAT_CharUpdateAcceleration);

		// We need to check the jump state before adjusting input acceleration, to minimize latency
		// and to make sure acceleration respects our potentially new falling state.
		CharacterOwner->CheckJumpInput(DeltaSeconds);

		// apply input to acceleration
		Acceleration = ScaleInputAcceleration(ConstrainInputAcceleration(InputVector));
		AnalogInputModifier = ComputeAnalogInputModifier();
	}

	if (CharacterOwner->GetLocalRole() == ROLE_Authority)
	{
		PerformMovement(DeltaSeconds);
	}
	else if (CharacterOwner->GetLocalRole() == ROLE_AutonomousProxy && IsNetMode(NM_Client))
	{
		ReplicateMoveToServer(DeltaSeconds, Acceleration);
	}
}

It would seem then that AddMovementInput expects a direction and a scalarValue completely separate from DeltaTime and that the good people at Epic handle the frame by frame predicted acceleration behind the scenes.

Also i could easily be very wrong lol but that’s what it looks like

Yes the movement component handles deltatimes and replication already.

Good example is the Shootergame for ue4 and Lyra in ue5