UNavLinkCustomComponent::OnLinkMoveFinished

Unless I completely misunderstand the concept behind it, the function UNavLinkCustomComponent::OnLinkMoveFinished is bugged. It doesn’t trigger when an agent reaches the end of the nav link. Instead, it triggers when the whole move/path is either finished or aborted, long after the link has been used. OnLinkMoveStarted works fine for me. I already posted this here.

Hey MaxPower42,

I’ve spent some time working on this but I’m not sure I’m seeing the same results.

Would you be able to provide the code and setup information that you are using, or even a simplified test project that showcases the issue so that I can take a closer look and see which steps I’m overlooking on my end?

Also, it’d be great if you could provide some information regarding what exactly you’re trying to accomplish so I can have a bit of context for the issue as well.

Thanks!

Well, I am not yet entirely sure what I’m trying to accomplish. I am rather trying to get an overview of usable pathfinding concepts at the moment, in order to get an idea of what can be accomplished and how.

In my project I am just placing my custom NavLink to mark a place where characters can “drop” down a short distance. They are using it, I am just missing the OnLinkMoveFinished event. It triggers too late, like I described.

A practical example would be a link that connects two rooms through a narrow ventilation shaft that is too low to walk through it, so a character would need to crouch. When it reaches the start of the link, it has to start crouching, which is not a problem, because OnLinkMoveStarted triggers precisely at that point. But since OnLinkMoveFinished doesn’t trigger when the character reaches the end of the link, I can’t make it stop crouching. Sure, I could work around that by using a seperate overlap-volume to make everyone crouch who is inside or close to the shaft, but that’s not the point.

I will post the code next, but I have to split the post because of the character limit.

header:

#pragma once

#include "AI/Navigation/NavLinkCustomComponent.h"
#include "NavLinkCompTest.generated.h"

UCLASS()
class PROJECT02_API UNavLinkCompTest : public UNavLinkCustomComponent
{
	GENERATED_BODY()
	
public:

	virtual bool OnLinkMoveStarted(UPathFollowingComponent* PathComp, const FVector& DestPoint) override;
	virtual void OnLinkMoveFinished(UPathFollowingComponent* PathComp) override;
	
};



UCLASS()
class PROJECT02_API ANavLinkActorTest : public AActor
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere)
	USceneComponent* RootComp;
	UPROPERTY(EditAnywhere)
	UNavLinkCompTest* LinkComp;

	ANavLinkActorTest();

	// just for debug-visualization:
	virtual void Tick(float DeltaTime) override;

};

cpp:

#include "Project02.h"
#include "NavLinkCompTest.h"

#include "Runtime/AIModule/Classes/Navigation/PathFollowingComponent.h"
#include "AIController.h"


bool UNavLinkCompTest::OnLinkMoveStarted(UPathFollowingComponent* PathComp, const FVector& DestPoint)
{
	//Super::OnLinkMoveStarted(PathComp, DestPoint);// empty function, only returns false

	GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Cyan, FString::Printf(TEXT("Link Move Started: %s on %s"), *PathComp->GetOwner()->GetName(), *GetOwner()->GetName()));

	return false;
}
void UNavLinkCompTest::OnLinkMoveFinished(UPathFollowingComponent* PathComp)
{
	//Super::OnLinkMoveFinished(PathComp);// empty function

	GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Blue, FString::Printf(TEXT("Link Move Finished: %s on %s"), *PathComp->GetOwner()->GetName(), *GetOwner()->GetName()));
}



ANavLinkActorTest::ANavLinkActorTest()
{
	RootComp = CreateDefaultSubobject<USceneComponent>("RootComp");
	SetRootComponent(RootComp);
	LinkComp = CreateDefaultSubobject<UNavLinkCompTest>("LinkComp");

	PrimaryActorTick.bCanEverTick = true;
}

void ANavLinkActorTest::Tick(float DeltaTime)
{
	//Super::Tick(DeltaTime);
	
	FVector p0 = GetActorLocation();
	FVector p1 = LinkComp->GetStartPoint();
	FVector p2 = LinkComp->GetEndPoint();

	DrawDebugPoint(GetWorld(), p0, 5.f, FColor::Yellow, false, 1.5f*DeltaTime);
	DrawDebugPoint(GetWorld(), p1, 8.f, FColor::Red, false, 1.5f*DeltaTime);
	DrawDebugPoint(GetWorld(), p2, 8.f, FColor::Green, false, 1.5f*DeltaTime);

	DrawDebugLine(GetWorld(), p1, p2, FColor::Yellow, false, 1.5f*DeltaTime);
}

I would expect to see the blue debug-message when an agent reaches the end of the link. Instead, I see it when the agent has completely finished moving or aborted the move.

Hey MaxPower42,

Thanks for the additional information. However, I’m having trouble getting your code to compile after making the necessary changes to get it to work with my project. Would you be able to create a simplified test project and provide it so I can take a closer look at your setup and see if there’s something I’m missing?