UNavigationPath isValid() acts weird ( Triggers __BreakPoint ) c++

hello everyone
i am using UNavigationSystemv1 to find path and it works well , but sometimes it crashes the editor

image

path is of Type UNavigationPath*

the error in output log is :

Script Stack (0 frames):

Assertion failed: (SharedPath.IsValid() && SharedPath->IsValid()) == !!bIsValid [File:D:\build\++UE5\Sync\Engine\Source\Runtime\NavigationSystem\Private\NavigationPath.cpp] [Line: 547] 

A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.

Can someone please help me to figure it out why calling path member functions trigger __debugbreak() while i have null check ?

1 Like

This works for me no with problems.

TArray<FVector> ANavTester::GetPathPoints() {
	TArray<FVector> points;

// where target is of type pointer to AActor;

	if (Target) {
		FVector targetLoc = Target->GetActorLocation();		
		UNavigationSystemV1* NavManager = UNavigationSystemV1::GetCurrent(GetWorld());
		check(NavManager);
		UNavigationPath* Path = NavManager->FindPathToLocationSynchronously(GetWorld(), GetActorLocation(), targetLoc, this);
		check(Path);
		FNavPathSharedPtr p = Path->GetPath();
		if (p.IsValid()) {
			const TArray<FNavPathPoint> npoints = p.Get()->GetPathPoints();
			for (FNavPathPoint point : npoints) {
				points.Add(point.Location);
			}
		}											
	}
	return points;		
}


Perhaps you left out checks for elements?

1 Like

‌Hey 3DRaven , thanks for your Response!

i tried the above way of doing it

I get an error says :

Exception thrown at 0x00007FFC1416CD7D (UnrealEditor-NavigationSystem.dll) in UnrealEditor.exe: 0xC0000005: Access violation writing location 0x0000000000000058.

waiting to hear from you !

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

Oops! my bad, the first solution works fine
in line
path->EnableDebugDrawing(true, FColor::Red);

p was lower case

, Thanks a lot my friend.

No problem. Happy coding :slight_smile:

1 Like