How to make vehicle parallel with surface

Hi there, I have recently been working on a space game and am currently working on ship mechanics.
I am trying to sort out the landing module, but I have run into a problem: aligning the ship with the surface that it is above. This is vital to provide a smooth experience when landing, and despite hours of research, I just can’t seem to figure out how to do it.

My current setup goes like this: cast a ray downwards 30 studs and check if there is a valid part to land on. The ray then returns the surface normal and position. Then, using some CFrame things that I got out of my research (which I don’t really understand), it calculates the angle at which the ship should be.

Or at least it should, however, that is not the case, as seen in this video below:

As you can see, it works when the part below it is at a specific rotation, but once that rotation is changed, it completely breaks.

Here is the script that I use in the video:

local part = game.Workspace.Ships.Eagle.Seat

function FindTerrainHeight(pos, ship)
    local origin = pos
    local direction = Vector3.new(0, -30, 0)
    local ray = Ray.new(origin, direction)

    local blackList = {ship}
    local ignoreWater = false
    local part1, intersection, surfaceNormal, surfaceMaterial = game.Workspace:FindPartOnRayWithIgnoreList(ray, blackList, ignoreWater)
    return part1, intersection, surfaceNormal, surfaceMaterial
end

local part1, pos, normal, material = FindTerrainHeight(part.Position, game.Workspace.Ships.Eagle)
local upVector = Vector3.new(0,1,0)
local rightVector = normal:Cross(upVector)
local upVector2 = rightVector:Cross(normal)
local resultPosition = CFrame.fromMatrix(pos, rightVector, upVector2)
local x, y, z = resultPosition:ToOrientation()
part.BodyGyro.CFrame = CFrame.Angles(y, x, z)

--print(part)
--print(pos)
--print(math.deg(normal.X)..", "..math.deg(normal.Y)..", "..math.deg(normal.Z))
--print(normal)
--print(material)
--local angle = math.deg(math.acos(Vector3.new(0,1,0):Dot(normal)/(Vector3.new(0,1,0).Magnitude * normal.Magnitude)))
--print(angle)
--print(part.CFrame.LookVector:Dot(CFrame.new(normal).LookVector))

The commented-out things are other solutions that I have tried, and they all failed.

I tried all combinations of x y and z in the CFrane.Angles() parameters to no avail.

I am at a complete loss for what to do, it feels like I have tried everything. Any help would be greatly appreciated.

Thanks in advance.

1 Like
1 Like

Thank you for the reply, but I don’t really understand anything in @EgoMoose’s tutorial, it is way too advanced for me, and I don’t see how the thread in which you made that reply could help me.
Is it possible for you to explain to me how that thread relates, or explain how I can go about solving my problem?

Thank you