Skip to main content
← Roadmap
🌊 Oceanology ProIn Progress6.0.0

Water queries from Blueprint

The runtime API any gameplay code can call to ask a water body for surface height, normal, depth, flow velocity and immersion at a world position.


Almost every water gameplay problem collapses into one question asked at a world position: where is the surface, which way does it face, how deep is the water, how fast is it moving, and is this point under it. Oceanology answers all five through a single query on the water component, and the same call works whether the component underneath is a river, a lake, an ocean or a custom body. The answer is assembled from the spline metadata, the terrain below, the active wave source, and where one covers the point, the live or baked shallow water simulation.

The query flags

A query declares up front what it wants through EOceanologyWaterBodyQueryFlags, so you never pay for a depth resolve you are not going to read. The component adjusts the set for you: asking for depth or immersion implies location, and asking for waves on a body that has them implies location and depth.

  • ComputeLocation - the point on the water plane, and the point on the wave surface when IncludeWaves is also set.
  • ComputeNormal - the plane normal, perturbed by waves when IncludeWaves is set.
  • ComputeVelocity - the water velocity vector at the point.
  • ComputeDepth - the water depth below the surface.
  • ComputeImmersionDepth - how far the query point sits under the surface. Greater than zero means underwater.
  • IncludeWaves - adds the wave perturbation. Requires one of the location, normal, depth or immersion flags.
  • SimpleWaves - the cheaper wave evaluation, which does not perturb the normal. Requires IncludeWaves.
  • IgnoreExclusionVolumes - skips the water exclusion volume test.

Calling it from Blueprint

Get Water Surface Info At Location is the Blueprint node on UOceanologyWaterComponent. It takes a world location and an Include Depth switch, and returns the water surface location, the surface normal, the water velocity and the water depth. It returns false when the point falls inside a water exclusion volume, and zeroes its outputs in that case, so a caller that ignores the return value still reads as out of water. Around it sit the smaller nodes: Get Max Wave Height, Get Water Velocity At Spline Input Key, Get Water Velocity Vector At Spline Input Key, Get Audio Intensity At Spline Input Key, Get Islands and Get Exclusion Volumes.

Calling it from C++

TryQueryWaterInfoClosestToWorldLocation takes the world location, the flag set, and an optional precomputed spline key, and returns a TValueOrError. The error side is typed: WaterBodyNotRegistered for a component that is not yet registered with its actor, NullWaterSplineMetadata for the narrow window before registration completes. The result exposes plane and surface variants of location, normal and depth, plus immersion depth, IsInWater, velocity, the wave info struct and IsInExclusionVolume. Each accessor asserts that the matching flag was requested, so a mismatched flag set fails loudly instead of returning a plausible zero.

Where each number comes from

  • Surface height - the component Z for lakes and oceans, which are flat surfaces; the spline location at the closest input key for rivers and custom bodies.
  • Depth - measured down to the terrain for oceans and lakes, read from the spline Depth curve for rivers and custom bodies. An ocean with no terrain under the query point falls back to r.Oceanology.OceanFallbackDepth.
  • Velocity - the spline Water Velocity Scalar curve evaluated at the closest key, applied along the spline, or the shallow water velocity where a simulation snapshot covers the point.
  • Waves - the active wave source (Gerstner, spectral Gerstner or FFT) plus the optional breaking wave leaf, attenuated by depth, added on top of the plane.
  • Shallow water - where a covering snapshot exists its height and velocity replace the analytic plane outright, and a covered but dry cell reports zero immersion with waves suppressed.

The same query from other systems

  • Niagara - the Oceanology water data interface exposes IsValid, GetWaterSurfaceInfo (world position in; surface position, depth, velocity and an in-exclusion-volume flag out) and GetWaveParamLookupTableOffset. A system can be bound to a body with Set Oceanology Water Component, or find the closest body on spawn.
  • Physics thread - CreateWavePhysicsQuerySnapshot publishes an immutable, UObject-free evaluator that Chaos can retain and evaluate while the game thread edits, replicates or regenerates the authoring wave source.
  • AI - the Inside Water Body environment query test scores items by immersion depth, with its own include-waves, simple-waves and ignore-exclusion-volumes switches.
  • Buoyancy - Get Last Water Surface Info returns the plane location, plane normal, surface position, depth, body index and velocity that the pontoon solver last used for that actor.

Against the previous API

BeforeOceanology Pro
Query failureQueryWaterInfoClosestToWorldLocation returned a filled struct with no way to signal an unusable bodyTryQueryWaterInfoClosestToWorldLocation returns a TValueOrError with a typed error the caller must handle
Spline flow dataA vector curve stored per spline pointA scalar curve applied along the spline tangent, so width and direction edits do not invalidate flow
Niagara bindingSet Water Body took the water actorSet Oceanology Water Component takes the component, which is what the query actually lives on
Query flags8, combinable
Water body types answered4 - River, Lake, Ocean, Custom
Blueprint nodeGet Water Surface Info At Location - location in, 4 outputs plus a depth switch
Spline point defaultsDepth 150 cm, River Width 2048 cm, Velocity 128, Audio Intensity 1
Ocean depth fallbackr.Oceanology.OceanFallbackDepth, 3000 cm
Generic depth fallbackr.Oceanology.FallbackDepth, 3000 cm
Flow encoded in the Water Info texturecapped by r.Oceanology.MaxFlowVelocity, 1024 cm/s
Shallow water wet/dry threshold0.01 cm
Repeat-query optimisationr.Oceanology.UseSplineKeyOptimization, on by default

This is one entry on the Galidar roadmap. For what already shipped in each release, see the Changelog.