Path finding to approach at specific distance

So, there are two characters, actor and target. Actor needs to approach to target at specific distance (minimal ability use distance). I’m using navigation system - find path. Start and end points are just centres of the characters. Logically, it’s an optimal way to search for the path. But in reality both characters are obstacles, and the path finding algorithm is trying to walk around these obstacles making some random paths, which are quite far from optimal. Changing navigation related properties doesn’t work, because apparently the navigation system needs time to update. Also, I can’t rely on the actor just passing by the target at some point close enough to stop and start using, because I need to show path and its cost before actually start walking.
Consequently, question, is there a built-in way to solve this, maybe there is just something that I don’t see. Also, plugins that solve this also would be good, but I want to know how it works, not only solve, so it’s last resort.


You could pre-calculate both paths to a series of points and then just feed them to the two AI’s There would be no interference between them because they would not know about each other.

You could use the AI avoidance controller for them to not get stuck on each other if they collide mid way through

Pre-calculation class


#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NavTester.generated.h"

UCLASS()
class YOUR_API ANavTester : public AActor
{
	GENERATED_BODY()
	
public:	

	ANavTester();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	

	virtual void Tick(float DeltaTime) override;

	UFUNCTION(BlueprintCallable)
		TArray<FVector> GetPathPoints();


	UPROPERTY(BlueprintReadWrite, editAnywhere)
		AActor* Target;

	UPROPERTY()
	class UNavigationSystemV1* NavManager;

	UPROPERTY()
		class UNavigationPath* Path;


	UPROPERTY(BlueprintReadWrite, EditAnywhere)
		FColor DebugColor = FColor::Red;

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
		bool Debug = false;

};

.cpp


#include "NavTester.h"
#include "NavigationSystem.h" 
#include "NavigationPath.h"


ANavTester::ANavTester()
{
 	// 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;

}

// Called when the game starts or when spawned
void ANavTester::BeginPlay()
{
	Super::BeginPlay();	
	NavManager = UNavigationSystemV1::GetCurrent(GetWorld());
}


void ANavTester::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

TArray<FVector> ANavTester::GetPathPoints() {
	TArray<FVector> points;

	if (Target) {
		FVector targetLoc = Target->GetActorLocation();				
		check(NavManager);
		Path = NavManager->FindPathToLocationSynchronously(GetWorld(), GetActorLocation(), targetLoc, this);
		if (Path != nullptr) {
			check(Path);
			FString s = Path->GetDebugString();
			if (GEngine)
				GEngine->AddOnScreenDebugMessage(2, 1, FColor::Cyan, s);
			Path->EnableDebugDrawing(true);

			FNavPathSharedPtr p = Path->GetPath();

			if (p.IsValid()) {
				const TArray<FNavPathPoint> npoints = p.Get()->GetPathPoints();
				for (FNavPathPoint point : npoints) {
					points.Add(point.Location);
				}
				if (Debug) {
					for (int i = 0; i < points.Num() - 1; i++) {
						DrawDebugLine(GetWorld(), points[i], points[i + 1], DebugColor, false, 0.1f, 0, 2);
					}
				}
			}
		}
	}
	return points;		
}