How to check if a point is reachable by pawn?

Given a point on the NavMesh, how can I determine if an AI Pawn can reach this point?

Basically the player makes a noise at position (x,y,z), then I pass this (x,y,z) to the AI Pawn.

Currently the AI Pawn will always walk towards (x,y,z) even if it can’t reach it and when this happens it just stays still.

I’m looking for a function similar to Get Reachable Point In Radius, but to be given (x,y,z) and output a boolean as to whether the AI Pawn can reach (x,y,z) i.e. it’s not behind an impassable wall.

Attached image to help explain this

Cheers

2 Likes

Depends.

For a C++ Project:

UNavigationComponent* PathFindingComp = FindComponentByClass<UNavigationComponent>();
     if (PathFindingComp != NULL) {
         bool bFoundPath = PathFindingComp->FindPathToLocation(dest, NULL);
         if (bFoundPath == false || PathFindingComp->GetPath().IsValid() == false) {
             bFoundPath = PathFindingComp->FindSimplePathToLocation(dest);
         }
        if (!bFoundPath) {
             // display some error here or whatever
        }
     }

For a Blueprint only project: Good luck :confused:

It’s in BP but easy enough to write a custom node. Will give it a try, cheers :slight_smile:

Apparently UNavigationComponent is deprecated? I can’t seem to access the class and that’s what I found in a thread on google

I’m trying with UNavigationSystem and then will try with UPathFollowingComponent. But I’m always sloooow with UE’s C++. Suggested code always seems to take ages to load suggestions - is that a problem on my end or just the size of the codebase?

Uh, sorry, didnt know that its deprecated. Will need to look for a current implementation.

So far I have

UNavigationPath* NavPath = UNavigationSystem::FindPathToLocationSynchronously(GetWorld(), PathStart, Position, NULL);

But I’m not sure what to do with the NavPath (where PathStart is the actor location, Position is where to move to) and this is called from a class which extends the AIController

For reproducibility, full code is:

UFUNCTION(BlueprintCallable, Category = "Midnight Sun BP Library")
	bool IsPositionReachable(FVector Position) {

		FVector PathStart = GetPawn()->GetActorLocation();

		UNavigationPath* NavPath = UNavigationSystem::FindPathToLocationSynchronously(GetWorld(), PathStart, Position, NULL);
		
		if (!NavPath)
			return false;

		
		return true;
	}

I think I’ve solved it, gotta test a bit more

UFUNCTION(BlueprintCallable, Category = "Midnight Sun BP Library")
	bool IsPositionReachable(FVector Position) {

		FVector PathStart = GetPawn()->GetActorLocation();

		UNavigationPath* NavPath = UNavigationSystem::FindPathToLocationSynchronously(GetWorld(), PathStart, Position, NULL);
		
		if (!NavPath)
			return false;

		return NavPath->IsValid();
	}

Nope I thought it worked, but it didn’t :frowning:

Got it!

UFUNCTION(BlueprintCallable, Category = "Midnight Sun BP Library")
	bool IsPositionReachable(FVector Position) {
		FVector PathStart = GetPawn()->GetActorLocation();
		UNavigationPath* NavPath = UNavigationSystem::FindPathToLocationSynchronously(GetWorld(), PathStart, Position, NULL);
		
		if (!NavPath)
			return false;

		return !NavPath->IsPartial();
	}

I prefer using the test path function instead. It works + it’s a lot faster:

bool UNavigationSystem::TestPathSync(FPathFindingQuery Query, EPathFindingMode::Type Mode, int32* NumVisitedNodes)

The behavior tree decorator BTDecorator_DoesPathExist uses that one if you want an example use.

Thank you! :slight_smile: I’m guessing you are the same person on Reddit who helped me, so thank you x 2!

You’re welcome :slight_smile: Same person.

The EQS will excel in this scenario also as the AI can pick a logical position instead of a random one. Plus it has the path test as an option ready to use :slight_smile:

In my case I needed to check if NavPath was valid, my return is:

return NavPath != nullptr && NavPath->IsValid() && !NavPath->IsPartial();