WaterSubsystem How does GetWaveHeightAtPosition Work???

I would like to understand how the GetWaveHeightAtPosition function works. I have tried this with a cube to float in the water using queries to the GetWaveHeightAtPosition function provided by the AWaterBody->GetWaterWaves->GetWaveHeightAtPosition. This however is providing inaccurate results to the observed waves? What am I doing wrong?

I created a Blueprint function library with the Function

UFUNCTION(BlueprintCallable)
static float GetWaterHeightAtLocation(const FVector& Location, const AWaterBody* WaterBody, FVector OutNormal);

with the implementation of the function as follows

float UWaterHelperLibrary::GetWaterHeightAtLocation(const FVector& Location, const AWaterBody* WaterBody, FVector OutNormal)
{
	if (WaterBody->GetWaterWaves())
	{
		float WaterTime{};
		if (UWaterSubsystem* WaterSubsystem = UWaterSubsystem::GetWaterSubsystem(WaterBody->GetWorld()))
		{
			WaterTime = WaterSubsystem->GetWaterTimeSeconds();
		}
		return WaterBody->GetWaterWaves()->GetWaveHeightAtPosition(Location, 0.0f, WaterTime, OutNormal);
	}
	return 0.0f;
}

Ensuring I have a WaterBodyCollision Preset

Currently, I have its settings to the following but I have changed it multiple times between Overlap and Block for the trace type and object type “water” and “water body”. Currently, it should be at “block” for both.

I then created a level with a “WaterBodyCustom,” “Water Zone,” and a Blueprint Cube to act as a floating object in the water.

I edited the WaterBodyCustom to ensure the water was not still and fluctuated in height.

Next on the BP_FloatingBox I during BeginPlay, I ensure it gets a reference to the WaterBodyCustom.

During the Tick, I get the actor’s location and pass the position over to the Helper Function. Then make a new position vector with the return as the new z position. I draw the positions for visual debugging. What I noticed was that the new position was drastically different from what I was hoping to see. Which was at least close to the water surface level beneath the cube.


Correction Factor is set to 1 so shouldn’t be doing anything atm… I was experimenting XD.

This is what I observed

Any advice to find the accurate position of the WaterBodyCustom Surface at a location would be great.

Note: I have briefly looked in the UGerstnerWaterWaves::GetWaveHeightAtPosition Found in the GerstnerWaterWaves.cpp which appears to sum each GerstnerWave height to produce the output. Though I haven’t had too much time to dive deep into Gerstner waves. Though I assume from the comments /** Computes the raw wave perturbation of the water height/normal */ it should be the wave height. The word Raw does raise questions on if other steps occur elsewhere for the end resulting wave height?