Have part collide with water but not terrain?

I’m scripting a boat. To make it float as expected, I have every visual part set to massless and one part beneath the water line to act as the boat’s density. This system works well for making the boat float.

The problem occurs when the boat runs into terrain. Sometimes it will rise up and become stuck because of the density part colliding with the terrain. The density part obviously has to be CanCollide true so that it collides with the water. My question is, how do I make it so that this part will collide with water but not terrain? I’m using smooth terrain water and terrain. Is there a way I can set the collision group of water separately to terrain?

To my knowledge, I do not think this is possible due to Terrain being considered 1 entity. You may be able to get a workaround using some rays and be able to check the material nearest to it, but probably not as good as what you’re looking for. If not, you might have to consider a mechanic where you can simply push the boat around a bit when it gets stuck on land.

I’m not experienced with them, but you can try using Collision Filtering.

Terrain is a complete entity and cannot be seperated by the type of terrain it is. Seems like you have somewhat of an XY problem here though. Rather than trying to prevent the boat from colliding with non-water terrain, why not just prevent collisions at all by raycasting or any other method of your choosing and keeping the boat away from land?

The density part needs to have collisions so that it collides with water. This is the part that causes problems when it collides with regular terrain.

It needs to be able to collide with water so that water friction is accounted for when driving the boat. I use BodyPosition anyway to keep the boat at the correct Y position (so the density part doesn’t really matter for buoyancy). I think I might have just figured out a solution to the problem while typing this out and thinking through my situation more clearly.

You will have to rethink your implementation and terrain cannot be separated in any way. To start, your issue is that you want to simulate buoyancy and friction without interacting with any solids.

The friction is the easiest part and can be achieved with a VectorForce which acts at the center of mass (or somewhere below, but ignore this for the sake of simplicity).

For buoyancy, you will want to cast rays under the boat with the whitelist only including terrain. You can then apply the forces for each point of a casted ray with the magnitude depending on the distance from water (0 if none).

First check for water, then apply buoyancy and then the friction depending on how many rays hit the water.

1 Like

why not make it so the boat cannot collide with an otherwise transparent wall around each island ?

That’s the last resort in case nothing else that I try works because it would take a while and be a lot of manual labor on my part. There are no collision problems if I do that but it would just take forever to go around the entire map. It’s a pretty big map.

what if you used a very large cylinder ?

Thinking alternatively here-
Depending on your game, and how your boat is programmed to move, you could do what I do and just drastically reduce the boat’s speed if a ray below it detects that it’s on land. Players will be encouraged to pilot the boat off land, and it could lead to some exciting, sandbox-y interactions with the world.

If it’s imperative that your boats never goes on land, and your map has a fixed sea-level, you could make great use of a BodyGyro.
(note when other forces fight against the BodyGyro, such as when the boat collides with something, this can cause the boat to flip out… all depends on Gyro’s strictness)

Ultimate control can be achieved by locally rendering the boat with CFrame on RenderStepped. I saw a really great speedboat demo a few years back that was entirely CFrame driven. All parameters were under control, but the code got pretty technical.

Using raycast to detect when the boat is on land would be pretty easy, but my issue is that the boat collides with terrain in the first place. The second it hits the terrain, it gets stuck. Here’s a gif of what I mean:
https://gyazo.com/8c529c1597efcbedfb22430cbe50f820

This mainly happens when the boat hits terrain with the rock material, although it still happens with all other materials.

I use a BodyGyro already to keep the boat upright and to achieve a swaying motion. How could I use a BodyGyro to keep the boat away from land? I also use a BodyPosition to keep the boat at the correct water level so that I don’t have to fiddle with density to get the boat to float.

Sorry, I totally meant BodyPosition, not BodyGyro.

A BodyPosition set at sea-level with high enough strictness on the Y axis should prevent your boat from going up onto the terrain.

I am curious though, what is causing your boat to get stuck the moment it goes on terrain? Are you using a BodyForce that is too weak to overcome the friction?

To move the boat I used a VectorForce. Really I don’t know what causes it to get stuck because I’ve tried adding a hitbox part in the front of the boat, but that also gets stuck. To me it looks like it’s a result of weird collisions where the terrain meets the water. I have a BodyPosition set to keep it at sea level, but no matter how powerful it is, the boat will still ride up the terrain when it comes into contact with it.

For now I’ve temporarily fixed the problem by using raycast to detect if the boat is in shallow water, as well as a ray to detect if the front of the boat is close to hitting terrain.

One thing I had to overcome in my game when designing islands was ensuring that the terrain was higher than the water. I achieved this by painting the terrain onto the water, rather than by growing it up from the ocean floor. Something about the way the Grow tool works causes the shoreline to be slightly underneath sea level.

Example of using the Grow tool (look at the shore in the foreground, how it is lower than the water)

Example of painting the terrain onto the water (see how it is above sea level)

Your boat may not be colliding with the terrain because it is impacting a piece that is lower than (or exactly at) sea level. This likely wouldn’t happen with a strict BodyPosition in the 2nd terrain example above, especially since most of the boat is underwater. You did well to ensure that the front of the boat has a wall-like part for colliding with terrain, without it, your boat is more likely to climb the shore.

2 Likes

The map that I’m using is just a generated map for testing purposes. I’ll make sure to tell my partner who will be making the terrain about that. Thanks

1 Like