Cumulative offset error when setting actor location

Hey guys, so I coded an infinite moving grid system that simulates an infinite runner by recycling types that have passed the player and moving them to the front of the grid. this worked great until I added horizontal movement. For some reason, a gap appears between the tiles over time that grows when I move the tiles horizontally, and I can’t figure out where the issue would be.Anyone have an idea? The horizontal movement code is located inside the ResetPastTiles function. Thanks for the help

// Called when the game starts or when spawned
void AGridManager::BeginPlay()
{
	Super::BeginPlay();
	PopulateGrid();
	PlaceTiles();
	GenerateSpawnLocations();
	StartMovement();
}

// Called every frame
void AGridManager::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
	ResetPastTiles();
}

void AGridManager::PopulateGrid()
{
	//Initialize Tiles
	groundTiles = TArray<TArray<AGroundTile*>>();

	//Populate 2D array of tiles
	for (int i = 0; i < gridHeight; i++)
	{
		TArray<AGroundTile*> tempArray = TArray<AGroundTile*>();
	
		for (int i = 0; i < gridWidth; i++)
		{
			AGroundTile* tempTile = GetWorld()->SpawnActor<AGroundTile>(AGroundTile::StaticClass());
			UStaticMeshComponent* tileMeshComponent = (UStaticMeshComponent*)tempTile->GetComponentByClass(UStaticMeshComponent::StaticClass());
			tileMeshComponent->SetStaticMesh(tileTypes[0]);

			tempArray.Add(tempTile);

		}
		groundTiles.Add(tempArray);
	}

	leftTileColumn = 0;
	rightTileColumn = gridWidth - 1;
}

void AGridManager::PlaceTiles()
{
	tileSize = FVector();

	for (int i = 0; i < gridHeight; i++)
	{
		for (int j = 0; j < gridWidth; j++)
		{
			AGroundTile* tempTile = groundTiles[i][j];
			//Generate position for new Tile
			float xOffset = i + 1;
			float yOffset = j + 1;
			FVector tileOrigin = FVector();
			tempTile->GetActorBounds(false,tileOrigin,tileSize);

			FVector tileLocation = FVector(GetActorLocation());
			tileLocation.X += xOffset * tileSize.X * 2;
			tileLocation.Y += yOffset * tileSize.Y * 2;

			tempTile->SetActorLocation(tileLocation);
		}
	}
	leftEdge = groundTiles[0][0]->GetActorLocation().Y - tileSize.Y;
	rightEdge = groundTiles[0][0]->GetActorLocation().Y + gridWidth * tileSize.Y + (tileSize.Y * 2);

}

void AGridManager::StartMovement()
{
	for (int i = 0; i < gridHeight; i++)
	{
		for (int j = 0; j < gridWidth; j++)
		{
			groundTiles[i][j]->MoveSpeed = MoveSpeed;
			groundTiles[i][j]->StartMoving();
		}
	}
}

void AGridManager::GenerateSpawnLocations()
{
	for (int i = 0; i < gridWidth; i++)
	{
		FVector location = groundTiles[gridHeight - 1][i]->GetActorLocation();
		AActor* newSpawnActor = GetWorld()->SpawnActor<AActor>(AActor::StaticClass());
		USceneComponent* sceneComponent = NewObject<USceneComponent>(newSpawnActor);
		sceneComponent->RegisterComponent();
		newSpawnActor->SetRootComponent(sceneComponent);

		newSpawnActor->SetActorLocation(location);
		spawnLocations.Add(newSpawnActor);
	}
}

void AGridManager::ResetPastTiles()
{
	//Move tiles that have passed the farther point of the grid system back to the top
	if (groundTiles[closestTileRow][0]->GetActorLocation().X < GetActorLocation().X)
	{
		for (int i = 0; i < gridWidth; i++)
		{
			groundTiles[closestTileRow][i]->SetActorLocation(spawnLocations[i]->GetActorLocation());
		}
		closestTileRow++;
		if (closestTileRow >= gridHeight)
		{
			closestTileRow = 0;
		}
	}
	//Move tiles that have gone too far left back to the right edge
	if (groundTiles[0][leftTileColumn]->GetActorLocation().Y < leftEdge)
	{

		spawnLocations[leftTileColumn]->SetActorLocation(FVector(spawnLocations[leftTileColumn]->GetActorLocation().X, rightEdge, GetActorLocation().Z));

		for (int i = 0; i < gridHeight; i++)
		{
			groundTiles[i][leftTileColumn]->SetActorLocation(FVector(groundTiles[i][leftTileColumn]->GetActorLocation().X, spawnLocations[leftTileColumn]->GetActorLocation().Y, GetActorLocation().Z));

		}

		rightTileColumn = leftTileColumn;
		leftTileColumn++;

		if (leftTileColumn >= gridWidth)
		{
			leftTileColumn = 0;
			rightTileColumn = gridWidth - 1;
		}
	}
	//Move tiles that have gone too far right back to the left edge
	if (groundTiles[0][rightTileColumn]->GetActorLocation().Y > rightEdge)
	{

		spawnLocations[rightTileColumn]->SetActorLocation(FVector(spawnLocations[rightTileColumn]->GetActorLocation().X, leftEdge, GetActorLocation().Z));

		for (int i = 0; i < gridHeight; i++)
		{
			groundTiles[i][rightTileColumn]->SetActorLocation(FVector(groundTiles[i][rightTileColumn]->GetActorLocation().X, spawnLocations[rightTileColumn]->GetActorLocation().Y, GetActorLocation().Z));
		}


		leftTileColumn = rightTileColumn;
		rightTileColumn--;

		if (rightTileColumn < 0)
		{
			leftTileColumn = 0;
			rightTileColumn = gridWidth - 1;
		}
	}
}

void AGridManager::TranslateTiles(float input)
{
	input *= HorizontalMoveSpeed;

	for (int i = 0; i < gridWidth; i++)
	{
		//Translate spawn Locations
		FVector location = FVector(spawnLocations[i]->GetActorLocation().X, spawnLocations[i]->GetActorLocation().Y - input * GetWorld()->GetDeltaSeconds(), spawnLocations[i]->GetActorLocation().Z);
		spawnLocations[i]->SetActorLocation(location);

		for (int j = 0; j < gridHeight; j++)
		{
			groundTiles[i][j]->MoveHorizontal(input);

			
		}
	}
}

bump for desperation

Scratch that, figured it out on my own. This method won’t work due to the variable nature of delta time overshooting the conditional check. Had to rewrite it where all tiles are placed each frame off a master tile.