is your targetLoc initialized? I do a check for my target actor before running anything.
Not getting any exceptions here.
Also did you make your TArray pathPoints a local variable or is it in your header?
Could it be that you are writing to a static var on many instances and it is causing the problem?
EnableDebugDrawing doesn’t seem to show any info on screen.
FString s = Path->GetDebugString();
seems to return the amount of points.
I do my own visualization from the points I get. Wasn’t event aware that path had a debug view.
Edit: Perhaps mark you TargetLoc as a UPROPERTY. It could be getting garbage collected mid calculation.
Made some optimizations and pushed some stuff to the header to not make it eat up as much memory
.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "NavTester.generated.h"
UCLASS()
class YOUR_API ANavTester : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ANavTester();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable)
TArray<FVector> GetPathPoints();
UPROPERTY(BlueprintReadWrite, editAnywhere)
AActor* Target;
UPROPERTY()
class UNavigationSystemV1* NavManager;
UPROPERTY()
class UNavigationPath* Path;
UPROPERTY(BlueprintReadWrite, EditAnywhere)
FColor DebugColor = FColor::Red;
UPROPERTY(BlueprintReadWrite, EditAnywhere)
bool Debug = false;
};
.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "NavTester.h"
#include "NavigationSystem.h"
#include "NavigationPath.h"
// Sets default values
ANavTester::ANavTester()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ANavTester::BeginPlay()
{
Super::BeginPlay();
NavManager = UNavigationSystemV1::GetCurrent(GetWorld());
}
// Called every frame
void ANavTester::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
TArray<FVector> ANavTester::GetPathPoints() {
TArray<FVector> points;
if (Target) {
FVector targetLoc = Target->GetActorLocation();
check(NavManager);
Path = NavManager->FindPathToLocationSynchronously(GetWorld(), GetActorLocation(), targetLoc, this);
if (Path != nullptr) {
check(Path);
FString s = Path->GetDebugString();
if (GEngine)
GEngine->AddOnScreenDebugMessage(2, 1, FColor::Cyan, s);
Path->EnableDebugDrawing(true);
FNavPathSharedPtr p = Path->GetPath();
if (p.IsValid()) {
const TArray<FNavPathPoint> npoints = p.Get()->GetPathPoints();
for (FNavPathPoint point : npoints) {
points.Add(point.Location);
}
if (Debug) {
for (int i = 0; i < points.Num() - 1; i++) {
DrawDebugLine(GetWorld(), points[i], points[i + 1], DebugColor, false, 0.1f, 0, 2);
}
}
}
}
}
return points;
}
Swap out YOUR_API with your api for tests.
oh and if you are doing multiplayer then add
if (Path != nullptr) {
before check(Path);
Updated top code with a revised version.
up until the end. Seems on client it may not be present (maybe there is a setting for client side pathfinding?)
Paths are only visualized on server through