The logic of updating the path is very close to the old AutoRun function called from PlayerTick. The component has its own PlayerTick and has no external dependency, so the order of call is not important.
void UAutoRun_CC::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
if (!IsValid(ControlledPawn) || !bAutoRunning) return;
const FVector LocationOnSpline = AutoRunSpline->FindLocationClosestToWorldLocation(ControlledPawn->GetActorLocation(), ESplineCoordinateSpace::World);
const FVector Direction = AutoRunSpline->FindDirectionClosestToWorldLocation(LocationOnSpline, ESplineCoordinateSpace::World);
if ((LocationOnSpline - CachedDestination).Length() > AutoRunAcceptanceRadius)
{
ControlledPawn->AddMovementInput(Direction);
}
else
{
Stop();
}
}
Pathfinding logic, very close to the original. Never called inside the module, as it expects a coordinate from an external controller.
void UAutoRun_CC::Start(const FVector& InDestination)
{
Stop();
if (UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), InDestination))
{
AutoRunSpline->ClearSplinePoints();
for (const FVector PointLoc : NavPath->PathPoints)
{
AutoRunSpline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World);
}
if (NavPath->PathPoints.Num() > 0)
{
CachedDestination = NavPath->PathPoints.Last();
bAutoRunning = true;
UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ClickEffect, CachedDestination);
}
}
}
Stopping and clearing values
void UAutoRun_CC::Stop()
{
if (!bAutoRunning) return;
bAutoRunning = false;
CachedDestination = FVector::ZeroVector;
AutoRunSpline->ClearSplinePoints();
}