How to read current NavArea in which character is?

Hello,

Does anybody know how to access NavArea in which is character standing ? I checked NavigationComponent but I can not find it here. Any ideas please ?

Thank you :slight_smile:

1 Like

#Video Pic For You

I am doing what you are asking in this picture below!

The nav area closest to the AI unit is being highlighted as they move!

Here’s a gif of my AI using my custom Nav components finding a jumping path to its target using only C++, and a simple nav mesh volume in editor. There are no special helpers in the level! This was all calculated in C++ !

#Code, FindNearestPoly

In my custom UPathFollowComponent I wrote the following:

NavNodeRef UJoyPathFollowCompHighest::NavPoly_FindNearest(const FVector & Loc, const FVector & Extent)
{
	if(!MovementComp) return false;
	//~~~~~~~~~~~~~~~~~~
	
	//Agent Properties
	const FNavAgentProperties* AgentProperties = MovementComp->GetNavAgentProperties();
	if(!AgentProperties) return false;
	//~~~~~~~~~~~~~~~~~~
	
	const ANavigationData* NavData = (AgentProperties != NULL) ? GetNavDataForProps(*AgentProperties) : GetMainNavData(FNavigationSystem::DontCreate);
	 
	if (NavData == NULL)
	{
		NavData = GetMainNavData();
	}
	 
	const ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
	if(!NavMesh)
	{
		ScreenMsg("UJoyPathFollowCompHighest::DrawNavTileBounds()>> Cast to recast nav mesh failed");
		return false;
	}
	
	return NavMesh->FindNearestPoly(Loc,Extent,NavData->GetDefaultQueryFilter());
}

#Recast

The focus of my code is that I had to cast the basic nav mesh ptr to ARecastNavMesh in order to access the desired function

:slight_smile:

#Extent

This determines how far above and below the point UE4 checks to find a valid nav area.

Enjoy!

#:heart:

Rama

3 Likes

Wohoo! I almost lost all hopes that anybody will answer my question… This looks like exactly what I was looking for Rama! I can’t belive I have not checked ARecastNavMesh class… as you say, that cast does magic and gives me access to many powerful functions. I think I can combine your function with ARecastNavMesh::GetPolyAreaID() to get my area.

Thank you very much Rama, this reply is amazing as your any other reply.

Hei,

Thanks for your code, it contributed to my game. I’m pasting my code because I spent a few minutes adapting it to Unreal 4.15.

#include "Runtime/Engine/Classes/AI/Navigation/NavigationSystem.h"
#include "Runtime/Engine/Classes/AI/Navigation/RecastNavMesh.h"

int32 AMyCharacter::GetNearestPolyAreaID()
{
	auto world = GetWorld();
	if (!world) return 0;

	auto navSystem = world->GetNavigationSystem();
	if (!navSystem) return 0;

	auto navData = navSystem->GetMainNavData(FNavigationSystem::DontCreate);
	if (!navData) return 0;

	const ARecastNavMesh * navMesh = Cast<ARecastNavMesh>(navData);
	if (!navMesh) return 0;

	auto loc = GetActorLocation();
	auto extent = FVector(100.0f, 100.0f, 100.0f);
	NavNodeRef poly = navMesh->FindNearestPoly(loc, extent, navData->GetDefaultQueryFilter());

	auto areaID = navMesh->GetPolyAreaID(poly);

	return areaID;
}

Hello Everybody,

I am coding a custom pathfinding algorithm and I needed to work with the NavMesh (Get all the polygons or it or the grid). Which i though was the solution when I was roaming Google and foun Rama’s code to do that. BUT… having implement it following his instruction, my code is not compiling despite the fact it is not complaining about any errors prior that. Here is my code :

My .h

#pragma once

#include "CoreMinimal.h"
#include "Navigation/PathFollowingComponent.h"
#include "XXXXPathfinding.generated.h"

class ANavigationData;
class ARecastNavMesh;
class UNavigationSystem;
class UWorld;


UCLASS()
class XXXX_API UXXXXPathfinding : public UPathFollowingComponent
{
	GENERATED_BODY()
public:
	UXXXXPathfinding(const FObjectInitializer& ObjectInitializeer);

	FORCEINLINE const ANavigationData *GetMainNavData(FNavigationSystem::ECreateIfEmpty CreateNewIfNoneFound)
	{ 
		UNavigationSystem *NavSys = GetWorld()->GetNavigationSystem();
		if (!NavSys) return NULL;
		return NavSys->GetMainNavData(CreateNewIfNoneFound);
	}

	//VERY IMPORTANT FOR CRASH PROTECTION !!!!!
	FORCEINLINE bool TileIsValid(const ARecastNavMesh *NavMesh, int32 tileIndex) const
	{
		if (!NavMesh) return false;
		//~~~~~~~~~~~~~~
		const FBox TileBounds = NavMesh->GetNavMeshTileBounds(tileIndex);
		return TileBounds.IsValid != 0;
	}

	bool GetAllPolys(TArray<NavNodeRef>& Polys);
	

protected:
	virtual void BeginPlay() override;		
};

my .cpp

#include "XXXXPathfinding.h"
#include "Engine/Engine.h"
#include "Runtime/Engine/Classes/AI/Navigation/NavigationSystem.h"
#include "Runtime/Engine/Classes/AI/Navigation/RecastNavMesh.h"

bool UXXXXPathfinding::GetAllPolys(TArray& Polys)
{
	if (!MovementComp) return false;
	//~~~~~~~~~~~~~~~~~~

	//Get Nav Data
	const ANavigationData* NavData = GetMainNavData(FNavigationSystem::DontCreate);

	const ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
	if (!NavMesh)
	{
		return false;
	}

	TArray<FNavPoly> EachPolys;
	for (int32 v = 0; v < NavMesh->GetNavMeshTilesCount(); v++)
	{

		//CHECK IS VALID FIRST OR WILL CRASH!!! 
		//     256 entries but only few are valid!
		// using continue in case the valid polys are not stored sequentially!
		if (!TileIsValid(NavMesh, v))
		{
			continue;
		}

		NavMesh->GetPolysInTile(v, EachPolys);
	}


	//Add them all!
	for (int32 v = 0; v < EachPolys.Num(); v++)
	{
		Polys.Add(EachPolys[v].Ref);
	}
}

void UXXXXPathfinding::BeginPlay()
{
}

My Message Log after complile failed

…source\XXXX\XXXXPathfinding.h(35) : error C2027: use of undefined type ‘UNavigationSystem’
…source\XXXX\XXXXPathfinding.h(11) : note: see declaration of ‘UNavigationSystem’
…source\XXXX\XXXXPathfinding.h(35) : error C2227: left of ‘->GetMainNavData’ must point to class/struct/union/generic type
…source\XXXX\XXXXPathfinding.h(43) : error C2027: use of undefined type ‘ARecastNavMesh’
…source\XXXX\XXXXPathfinding.h(10) : note: see declaration of ‘ARecastNavMesh’
…source\XXXX\XXXXPathfinding.h(43) : error C2227: left of ‘->GetNavMeshTileBounds’ must point to class/struct/union/generic type

To be honest I have no clue what it talking about… As far as I know everything is all there… Obviously my knowledge is lacking…

Thank you in advance for your support on this

You forward declared UNavigationSystem in your header, but then you wrote inline code accessing methods and properties of the class in the header as well. Forward declaring just tells the compiler “this is a class”; if you want to access a class’s internal properties you need to include the header file for the class.

This seemed very nice and I wanted to check if my players target area ID was the same as the one he is currently using but am struggling with the multiple deprecation and also because I am using a plugin and not the game code (thus using a const worldcontext ubject* to start with). Does anybody have an updated version of this ? Love !

Hello! Rama’s answer is the best as always!

I’m having problems to understand what the “Extent” parameter does in the function FindNearestPoly.
He says it’s how far above and below the point the search is done, but I don’t understand how that FVector’s coordinates are used to determine the extension of the search.

The other problem i’m having is when trying to re-convert the Polygon to world position coordinates.
What function should I use? I was trying with NavMesh->GetPolyCenter() but it doesn’t seem to answer the original point.