A hand-placed navlinkproxy has an event to tell you when you start using the link, AND a call to send back to the pathfollowingcomponent when you’re done:
/** called when agent reaches smart link during path following, use ResumePathFollowing() to give control back */
UFUNCTION(BlueprintImplementableEvent)
AIMODULE_API void ReceiveSmartLinkReached(AActor* Agent, const FVector& Destination);
/** resume normal path following */
UFUNCTION(BlueprintCallable, Category="AI|Navigation")
AIMODULE_API void ResumePathFollowing(AActor* Agent);
Without that ResumePathFollowing call, the pathfollowingcomponent won’t know the link ends until it either hits a new link or finishes the end of the path.
If you use a GeneratedNavLinksProxy (from experimental feature starting in 5.5 to generate these), there’s no similar ResumePathFollowing call, so the AI doesn’t have a good way to know it’s ended the custom link (even when it changes segments)
We can easily either modify the engine or add our own overridden GeneratedNavLinksPRoxy to implement this, but it feels like it should probably be present and consistent with the other NavLinkProxy version.
It looks like there’s nothing implemented directly by the engine for this. I also reviewed the commit where this feature was added, and I couldn’t find anything in the code that supports the desired behavior.
If you’re interested, here is the commit where they added the feature. It has not been modified since release:
It definitely seems like something that could be added to the class, but as of now, there’s no built-in support for it. I also checked the most recent engine versions, and the class still appears unchanged. For the time being, the best approach would be to implement this yourself, as you mentioned, and override the LinkProxyClass on your RecastNavMesh.
I can notify Epic about this, but they may take some time to review it and decide whether to add it to the engine.
I’ll keep digging into the system, but as you said, adding a function similar to ResumePathFollowing inside UGeneratedNavLinksProxy seems like the best option for now. I’ll update you if I find anything else.
void UGeneratedNavLinksProxy::ResumePathFollowingForAgent(AActor* Agent)
{
if (!Agent)
return;
// Resolve the pawn that owns this movement
APawn* Pawn = Cast<APawn>(Agent);
if (!Pawn)
Pawn = Cast<APawn>(Agent->GetInstigator());
if (!Pawn)
return;
AAIController* AIController = Cast<AAIController>(Pawn->GetController());
if (!AIController)
return;
UPathFollowingComponent* PathFollowingComp = AIController->GetPathFollowingComponent();
if (!PathFollowingComp)
return;
PathFollowingComp->FinishUsingCustomLink(this);
}
Did this in the base engine class, but of course can be done in a custom inherited class.