How to read landscape heightmap at runtime?

I want to read Landscape altitude (z value) given 2D coordinates (x and y values) from another actor at runtime.

  • Do I need a ALandscape* reference to access its properties?
    I tried to set Landscape object to that pointer using Blueprint but I got an error (ALandscape scene actor is private and cannot be reached by other actors). What am mistaken?

  • at first sight I founded a very long chain to reach something similar to what I’m asking

LandscapeProxy::GetLandscapeInfo()->XYtoComponentMap()[x,y]->HeightmapTexture->GetSurfaceHeight()
or should I look somewhere else?
anyway I’m not even sure about resolution of this value (does it returns the average height of the tile? the maximum?) Is there a way to find the exact z value?

All of this because I want to spawn an actor just a few meters above the terrain. I guess there is an easier way to do that…

I know this is Unreal Engine, but when i was unity, the landscape had a mesh component. So try getting a reference to the mesh component of the landscape. It should have some kind of property that you can get the z component, given an x-y coordinates.

Edit: Ill try it out when i get home on my project.

Thanks, let me know.

I’ve failed you lol. I tried to get coordinate data but it wasn’t working out. Sorry!

I recently had a similar problem and stumbled across this post. Now I have found a solution, so here it is:

First you need to somehow get an instance to your landscape (assuming you only have one in your level):

#include "Landscape/Landscape.h"
//...

UWorld* world = GetWorld();
if (world == nullptr)
	return;

// Find the active landscape
TActorIterator<ALandscape> landscapeIterator(world);
ALandscape* landscape = *landscapeIterator;

Now you can do a line trace where you only look at the landscape and no other object in the scene. The internal physx collision object is initialized from the heightmap data, so this line trace should be very fast and in theory it should have almost the same speed as doing a heightmap lookup:

FCollisionQueryParams collisionParams(FName(TEXT("FoliageClusterPlacementTrace")), true, this);
collisionParams.bReturnPhysicalMaterial = true;

FHitResult hit(ForceInit);
if (landscape->ActorLineTraceSingle(hit, rayStart, rayEnd, ECC_Visibility, collisionParams)) {
	// Do something
}

My solution…

And…

when I use code :

TActorIterator<ALandscape> landscapeIterator(world);

got an error like this:

error LNK2019: unresolved external symbol "__declspec(dllimport) private: static class UClass * __cdecl ALandscape::GetPrivateStaticClass(void)" (__imp_?GetPrivateStaticClass@ALandscape@@CAPEAVUClass@@XZ),

what heppened?

You probably need to add Landscape to the YourProject.Build.cs file. This solved it for me

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Landscape"});