Download

Problem with exporting nav mesh data.

Hello. The other day I asked around if there’s a good way to easily export navigation mesh data and after some googling I found ExportNavigationData() deep down inside the navigation system and it seems to be exactly what I’m looking for. But no matter how I use it it always crashes both the editor and standalone. This is the code I’ve been using(I’ve tried many variations in the path string to no avail):


	FWorldContext Context = GEngine->GetWorldContexts().Last();
	UWorld *World = Context.World();

	UNavigationSystem* NavSys = World->GetNavigationSystem();
	NavSys->GetMainNavData(FNavigationSystem::ECreateIfEmpty::Create)->GetGenerator()->ExportNavigationData(FString(TEXT("Test.obj")));

I figure the function is deprecated at this point or not maintained anymore so I moved on to trying to extract the information manually and export it myself. So I found Rama’s tutorial on custom AI navigation which has a method that extracts nav mesh data, I just don’t know how to interpret it. This is the code I have so far:


FWorldContext Context = GEngine->GetWorldContexts().Last();
	UWorld *World = Context.World();

	UNavigationSystem* NavSys = World->GetNavigationSystem();
	ANavigationData* NavData = NavSys->GetMainNavData(FNavigationSystem::ECreateIfEmpty::DontCreate);
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);

	TArray<FNavPoly> NavPolyIDs;
	for(int i = 0; i < NavMesh->GetNavMeshTilesCount(); i++)
	{
		const FBox TileBounds = NavMesh->GetNavMeshTileBounds(i);

		if(!TileBounds.IsValid)
			continue;

		NavMesh->GetPolysInTile(i, NavPolyIDs);
	}

	TArray<FVector> Verts;
	for(int i = 0; i < NavPolyIDs.Num(); i++)
	{
		Verts.Reset();
		if(NavMesh->GetPolyVerts(NavPolyIDs*.Ref, Verts))
		{
			DebugMessage("Poly start, num verts: %d", Verts.Num());
			for(int j = 0; j < Verts.Num(); ++j)
			{
				FVector Vert = Verts[j];
				DebugMessage("Vertex position: %f %f %f", Vert.X, Vert.Y, Vert.Z);
			}
			DebugMessage("Poly end");
		}
	}

First of all the polys sometimes contain 3 vertices, sometimes 4 and sometimes even 5. As far as I know UE4 only uses triangles and not quads(and certainly not pentagons). And secondly even if I have the vertices, how do I get the indices so I can build a mesh? Any help would be greatly appreciated because I’m a bit confused right now.

If someone else has used ExportNavigationData() and gotten it to work recently that would be amazing too. Sorry for the long thread. Thanks.

Edit: I found out that the navigation data generator always returns nullptr when I try to get it. But why? Is it only created momentarily and then destroyed after it has filled its purpose? Is there any way to force it to be recreated so I can use the export function? I tried this but it still doesn’t work:


	UNavigationSystem* NavSys = World->GetNavigationSystem();
	ANavigationData* NavData = NavSys->GetMainNavData(FNavigationSystem::ECreateIfEmpty::Create);
	NavData->ConditionalConstructGenerator();
	if(NavData->GetGenerator() == nullptr)
		DebugMessage("Generator is nullptr");
	else
		DebugMessage("Generator isn't nullptr");

Solved it! Here’s how to do it if anyone else is interested in it at some point. Go into Project Settings → Navigation Mesh and set runtime generation to dynamic. Then use this code:


	UNavigationSystem* NavSys = World->GetNavigationSystem();
	ANavigationData* NavData = NavSys->GetMainNavData(FNavigationSystem::ECreateIfEmpty::DontCreate);
	ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
	NavMesh->GetGenerator()->ExportNavigationData(FString(TEXT("FOLDERLOCATION\\NAMEOFYOURFILE")));

Your navigation mesh should be exported as an .obj file with specified name in specified folder.

sorry to resurrect your old thread. I’m also trying to export my navmesh. i got the code working but somehow it exports a wrong mesh instead of the navmesh (the exported one looks like some sort of collision model?) i’m trying to get the playable space. (see pics)
edit: i use 4.18, in 4.20 navmesh c++ code is different (own module)
the code i use:


#include "Runtime/Engine/Public/Engine.h"
#include "Runtime/Engine/Classes/Engine/World.h"
#include "Runtime/Engine/Classes/AI/Navigation/RecastNavMesh.h"
#include "Runtime/Engine/Public/AI/Navigation/RecastNavMeshGenerator.h"
#include "GetNavmesh.h"
#include "AIController.h"

void AGetNavmesh::BeginPlay()
{
Super::BeginPlay();
FWorldContext Context = GEngine->GetWorldContexts().Last();
UWorld *World = Context.World();
UNavigationSystem* NavSys = World->GetNavigationSystem();
ANavigationData* NavData = NavSys->GetMainNavData(FNavigationSystem::ECreateIfEmpty::DontCreate);
ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
NavMesh->GetGenerator()->ExportNavigationData(FString(TEXT("C:\\Users\\xxxx\\Testnavmesh.obj")));
UE_LOG(LogTemp, Warning, TEXT("NavMeshExported"));
}

I have defined one agent in the project settings.
also i can’t package the game when using this code, compiling works without probs

I also do the same thing。after studing the code


for (int32 Index = 0; Index < NavSys->NavDataSet.Num(); ++Index)
    {
        // feed data from octtree and mark for rebuild                
        TNavStatArray<float> CoordBuffer;
        TNavStatArray<int32> IndexBuffer;
        const ARecastNavMesh* NavData = Cast<const ARecastNavMesh>(NavSys->NavDataSet[Index]);
        if (NavData)

it look like some kind of data in UWORD, but i can’t figure out what’s mean of this
v 360.000000 125.000000 -279.999939
v 390.000000 125.000000 -479.999969
v 360.000000 125.000000 -479.999969
v 390.000000 125.000000 -479.999969
v 360.000000 125.000000 -279.999939
v 390.000000 125.000000 -279.999939
v 390.000000 144.999985 -480.000000
v 390.000000 125.000000 -279.999939
v 390.000000 144.999985 -279.999969
v 390.000000 125.000000 -279.999939
v 390.000000 144.999985 -480.000000
v 390.000000 125.000000 -479.999969
v 390.000000 144.999985 -480.000000
v 360.000000 125.000000 -479.999969
v 390.000000 125.000000 -479.999969
v 360.000000 125.000000 -479.999969
v 390.000000 144.999985 -480.000000
v 360.000000 144.999985 -480.000000
v 360.000000 125.000000 -279.999939
v 390.000000 144.999985 -279.999969
v 390.000000 125.000000 -279.999939
v 390.000000 144.999985 -279.999969
v 360.000000 125.000000 -279.999939
v 360.000000 144.999985 -279.999969
v 360.000000 144.999985 -480.000000
v 390.000000 144.999985 -279.999969
v 360.000000 144.999985 -279.999969
v 390.000000 144.999985 -279.999969
v 360.000000 144.999985 -480.000000
v 390.000000 144.999985 -480.000000
v 360.000000 144.999985 -279.999969
v 360.000000 164.999985 -480.000000
v 360.000000 144.999985 -480.000000
v 360.000000 144.999985 -279.999969
v 360.000000 125.000000 -279.999939
v 330.000000 125.000000 -279.999939
v 360.000000 144.999985 -279.999969

bump. cant get it work and i cant get my head around why. tried in various projects and levels, everytime it exports some typ of collisionmodel. i want to make the navmesh slightely visible during runtime, so the user knows where he can teleport to in VR. How does everybody else do this?

just tried with 4.21, same result
changed code to meet the 4.20 programming updates


FWorldContext Context = GEngine->GetWorldContexts().Last();
    UWorld* World = GetWorld();
    UNavigationSystemV1* NavSys = FNavigationSystem::GetCurrent<UNavigationSystemV1>(World);
    ANavigationData* NavData = NavSys->GetDefaultNavDataInstance(FNavigationSystem::ECreateIfEmpty::DontCreate);
    ARecastNavMesh* NavMesh = Cast<ARecastNavMesh>(NavData);
    NavMesh->GetGenerator()->ExportNavigationData(FString(TEXT("C:\\Users\\xxxx\\Navmesh")));



ha

have you solved this question, i have the same problem!