Make Character Movement tile based.

I am trying to create ACharacter that should snap to grid positions when moving.

Approach

My conceptual approach is to have an axis event than when trigger I apply add the movement one time forward based on the grid size and then wait for a certain delay and apply the movement again.

If the player would press the forward axis continuously what would happen is the following:
MoveForward(gridsize), Wait(1s), MoveForward(gridsize), Wait(1s), ... etc

I am have written some C++ code to achieve this idea but the problem is that when calling AddMovementInput the player does not move.
The player would move forward everyframe if I would call AddMovementInput without the if condition above.



void AMyCharacter::MoveForward(float AxisValue)
{
	
	if(AxisValue > 0 && GetWorld()->GetTimeSeconds() - currentTime > MovementDelay)
	{      
         // add movement only after a delay has passed.
         // this place of the gets reached correctly but the player does not move
		AddMovementInput(GetActorForwardVector(), AxisValue * MovementSpeed,true);
		currentTime = GetWorld()->GetTimeSeconds();
	}
	if(AxisValue > 0)
	{
		UE_LOG(LogTemp, Warning, TEXT("Axis value %f"), AxisValue);
		UE_LOG(LogTemp, Warning, TEXT("Current Movement Input (%f %f %f)"), ControlInputVector.X, ControlInputVector.Y, ControlInputVector.Z); // (100,0,0) one time and the rest if (0,0,0)
	}
}


void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{ 
	Super::SetupPlayerInputComponent(PlayerInputComponent);
        // bind forward axis
	PlayerInputComponent->BindAxis("Move Forward / Backward", this, &AMyCharacter::MoveForward);

}

Problem

Player does not move at all.

For debugging purposes I printed the ControlInputVector and in the log I can see that is (0,0,0) every time except for one print when it is (100,0,0) which is good.

What have I tried?

  1. I tried setting bForce to true or false with no luck
  2. I tried reading the sourcecode of ACharacter and APawn and I found the function that consumes the input but I did not find the place where the location of the player get’s updated.

Any help would be appreciated.

At first glance it looks like “GetWorld()->GetTimeSeconds()” and “currentTime” will always be equal.

Looks like “currentTime” is meant to be a time accumulator and probably every Tick() you should just be incrementing it by DeltaTime. Then when a successful move occurs reset it to zero.

CurrentTime is the time when the last move was performed. Initially no moved was performed so the timer CurrentTime is set to 0.
After a time of let’s say 1 second a move can be made and the CurrentTime is updated to 1.