Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Hi there! First of all, thank you for creating this amazing plugin. I purchased the full version of Ocean3D, and the wave visuals and physics look absolutely incredible!

I am currently working on a survival/Palworld-style 3D game in Godot 4.7. My player character is a CharacterBody3D (kinematic, capsule collision) rather than a RigidBody3D. I want the player to be able to swim directly in the ocean without any vehicles, seamlessly riding the waves up and down (keeping the body vertical, just matching the water height seamlessly).

Since your built-in FloatingBody script is strictly designed for RigidBody3D (using forces and torques), it doesn't work out-of-the-box for a kinematic player.

Currently, I am manually querying Ocean.get_height(x, z) inside _physics_process to lerp the player's Y-velocity based on the submersion depth.

I would love to know:

  1. Is Ocean.get_height(x, z) the most performant and recommended API for a kinematic CharacterBody3D player to sample wave heights?
  2. Are there any built-in methods, components, or best practices in the full version specifically tailored for kinematic characters/swimming that I might have missed?

Thank you again for your hard work and support!

Hi! Thanks for the kind words, and great question. You are already on the recommended path, so let me confirm the details.

1. Yes, Ocean.get_height(x, z) is the right API, and it is cheap. Under the hood it runs the Gerstner sum for at most 4 waves, times 3 fixed-point iterations to invert the horizontal displacement. That is pure trig with no allocations, so one call per character per physics tick is negligible. You could take hundreds of samples per frame before it showed up in a profile. It is also guaranteed to match the rendered surface exactly: the physics math and the shader are mirrored by contract, which is the core idea of the addon.

2. The one thing you likely missed: Ocean.get_surface_velocity_y(x, z). For seamless wave riding, the trick is to give your character the water's own vertical velocity first, and only then correct the remaining depth error. Damping against the moving surface instead of world rest is exactly how FloatingBody rides waves, and this function is the one-off query version of that. Something like:

# in _physics_process, while swimming var x := global_position.x var z := global_position.z var target_y := Ocean.get_height(x, z) + FLOAT_OFFSET  # e.g. -1.0 for chest-deep var water_vy := Ocean.get_surface_velocity_y(x, z) velocity.y = water_vy + (target_y - global_position.y) * BOB_STIFFNESS move_and_slide()

With BOB_STIFFNESS around 3 to 6 you get a body that tracks swells 1:1 with a soft bob, instead of the slight lag or overshoot you tend to get lerping height alone. Since you are keeping the body vertical, one sample at the capsule's (x, z) is all you need; a prone swimmer would sample fore and aft to pitch with the wave, same API.

There is no dedicated kinematic component in the full version today. FloatingBody is deliberately RigidBody3D-only, because real force-based buoyancy is what it exists for. So you have not missed a component, and your approach is the same one I use for the swimmer in Driftline, the game this addon was extracted from: a kinematic body sampling get_height directly. A small CharacterBody3D swim helper is a good idea though, and I have noted it as a candidate for a future update.

One extra tip: Gerstner waves also displace water horizontally. If you ever want swimmers to feel a gentle push from big swells, Ocean.get_displacement(x, z) gives you the full 3D offset to derive that from. Optional flavor, but it sells storm swimming.

If you're liking the pack, a review would be super helpful for me, as the pack doesn't have any reviews yet. 

Thanks again for picking up Ocean3D, and good luck with the game!