Repathing no longer works on vector targets

ANavigationData::RequestRePath no longer works correctly if the target is a FVector rather than an AActor. (i.e. it was set up via FAIMoveRequest::SetGoalLocation rather than FAIMoveRequest::SetGoalActor, before being passed to AAIController->MoveTo).

It appears that was a result of this change:
https://github.com/EpicGames/UnrealEngine/commit/48331caa30db5ac914681a54cab4ff5753786fde#diff-15859a9cc76ea497ddf16d386bc55faa

That change in NavigationData.cpp means that it’s no longer sufficient to have bUpdateEndPointOnRepath set to true to force a repath; GetGoalActor() must return a non-null value, which won’t happen when the target is an FVector.

The workaround involves forcing a manual update of the EndLocation for the repath, and will look a bit like this, before any relevant call to RequestRepath:

FPathFindingQueryData PathQueryData = Path->GetQueryData();
PathQueryData.EndLocation = YourDesiredNewDestinationHere;
Path->SetQueryData(PathQueryData);

(Get the underlying FNavigationPath from the UPathFollowingComponent for the above).

Hey Kylotan,

Thanks for the report. Would you mind providing a functional example of this issue occurring?

Could you provide the code that you are using so that I can take a closer look at your setup?

Unfortunately I can’t share the code publicly. But all the important details are above - the code simply won’t recalculate EndLocation if there’s no GoalActor, so it can’t work.

Ah, okay, I overlooked it earlier but I see what you’re referring to now.

Just to clarify, is this the code that you are referring to in NavigationData.cpp?

if (PathToRecalculate->ShouldUpdateEndPointOnRepath() && (PathToRecalculate->GetGoalActor() != nullptr))
	{
		const FVector NewEndLocation = PathToRecalculate->GetGoalLocation();
		if (FAISystem::IsValidLocation(NewEndLocation))
		{
			EndLocation = NewEndLocation;
		}
	}

Also, you state that it no longer works correctly. Which version were you working in when you experienced different behavior?

Thanks

Yes, that is the change in question, specifically the addition to the if statement on the first line. I don’t know the exact version we were on when behaviour was different but it would have been a year ago or so.

Great, thanks for the clarification. I’ve reached out to our developers and I’ll respond as soon as I hear back with a solution.

I’m not sure I understand your issue. Auto-repathing is done when underlying navmesh changes, or when the move goal moves. Vectors (as move goals) don’t normally move on their own, so if you want to reuse path object by changing path’s goal location and repathing you’ll have to do it on our own. Your workaround is actually a proper way of implementing it.

Cheers,

–mieszko

In our case, the goal has moved, just that there’s no way to represent that without making it into an actor, which we don’t want to do. We’re happy with using the workaround, but it feels wrong that ShouldUpdateEndPointOnRepath() can be true and yet nothing happens, or that the constructor will fix up EndLocation for us in one circumstance (actors) and not the other (vectors), and that GetGoalLocation() is out of sync with EndLocation in the vector case.