How to find an angle using two rays using raycasting? (making ocean waves)

  1. What do you want to achieve?
    I am making custom waves for sailboats in my game. How would I make a ship be level with the waves/water using raycasting?

  2. What is the issue?
    I used ocean an mesh I made from blender, which is 162 tris so collision accuracy isn’t an issue. meaning if I cast a ray from a ship, the positions are accurate. The issue is, how do make the orientation relative to the wave? The wave is a meshpart, and it is anchored so it’s still.

here is a drawing of what I mean by 2 rays. Red being the rays, blue the ocean, and yellow the ship

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried making 2 new parts with their positions being the positions of where the rays hit for each ray on the ship, and trying to link them. That would work, but I couldn’t make it work.

I know about subtracting CFrames to make them face each other, but I don’t know how to get two CFrames using two rays.

Here is a screenshot of the ocean, and the collisions so you can get an idea

You can get the angle to be rotated like this:

local angle = math.acos(Vector3.new(0,1,0):Dot(RayNormal))
2 Likes

How would I incorporate the 2nd ray into this?

OK look I have an idea, I’m not sure if it would work:
First find the difference in heights of the parts on the boat and the corresponding part of the waves below. Then subtract that height from the parts on the boat and add the size of the part back so that it is nicely sitting on the waves.
Next find the angle in both cases, like I mentioned above, and update the CFrame like this:

local axis =  Vector3.new(0, 1, 0):Cross(RayNormal)
partOnBoat.CFrame = partOnBoat.CFrame * CFrame:FromAxisAngle(axis,angle)

Again, I’m no expert on this but it’s worth a try.

Is RayNormal the ray without workspace:FindPartOnRay or is it the Vector3 outcome of where the ray hit?

It is the surface normal of where the ray hit.

local part,pos,normal = workspace:FindPartOnRay(ray)

I found a solution. I took the 2 ray’s positions, and made the ship face them if that makes sense.

	local part2, pos2 = workspace:FindPartOnRayWithWhitelist(sternray, wavelist)
	local part, pos = workspace:FindPartOnRayWithWhitelist(bowray, wavelist)
	
	if part or part2 then
		script.Parent.CFrame = CFrame.new(pos, pos2)
	end ```
This works perfectly, I appriciate your help!
2 Likes