Wall collision detection for grid-based movement

This may not be the best solution but may help as there are many different possible solutions to your problem. I just made a simple actor that would contain a collision component and obviously your walls will also need a collision component to them.

In your .h

#pragma once

#include "GameFramework/Actor.h"
#include "movingActor.generated.h"

UCLASS()
class EXPERIMENTINGPROJECT_API AmovingActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AmovingActor(const FObjectInitializer& ObjectInitializer);

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UBoxComponent* restrictionBounds;
	
	//This is the function that will be bound to the OnComponentBeginOVerlap delegate of the
	//restructBounds collision component.
	void OverlapBeginFunction(class AActor* OtherActor, class UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
};

and in your .cpp

#include "experimentingProject.h"
#include "movingActor.h"


// Sets default values
AmovingActor::AmovingActor(const FObjectInitializer& ObjectInitializer) : 
	Super(ObjectInitializer)
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	restrictionBounds = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("restrictionBounds")); //construct the box collision component
	RootComponent = restrictionBounds; //make restriction bounds the root component.
	restrictionBounds->SetBoxExtent(FVector(12.f, 12.f, 12.f));//setting the bounds of the collision comp, the FVector I gave is just an example
	restrictionBounds->OnComponentBeginOverlap.AddDynamic(this, &AmovingActor::OverlapBeginFunction);

}

// Called when the game starts or when spawned
void AmovingActor::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AmovingActor::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

void AmovingActor::OverlapBeginFunction(class AActor* OtherActor, class UPrimitiveComponent* OtherComp,
	int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	SetActorLocation(SweepResult.Location); //I'm basically setting the location of the actor to where it detected the hit.
											//This may not be a good solution. What I would suggest doing instead is track the
											//actor's previous location in your movement function and then setting the location
											//to that when you detect an overlap.
}