Howdy, lets say that a plane constantly changes its tilt up or down. How would I be able to find the angle of elevation given the length of the plane relative to the world, no matter the orientation of the plane.

(The wanted angle would be in degrees)

–SOLUTIONS I’VE TRIED–

DOT PRODUCT
I’ve tried using dot product, but given that there is no fixed length for the opposite and adjacent angle as the plane would be constantly changing its tilt, it hasn’t work for me at least on how I implemented it.

(platform is the plane part)

RAY CASTING
I’ve also thought of using ray casting but I feel like there is a better way than ray casting since there can be many edge cases that go along with it, for example what if the plane is not over a part, or what if the plane casts a ray that is thousands of studs away. This post on finding an angle of a wedge part has a somewhat similar approach to what I want to accomplish, but given that it’s ray casting, it won’t work for me. (if for some reason nothing else works, I will have to resort to ray casting)

RELATIVE TO A PART, NOT THE WORLD
Another solution I have been given, but wouldn’t work for me is this:

Given that there wouldn’t be a “v2” and it would only be relative to the world, I couldn’t find a way to reshape the formula given to fit my case.

TO EULER ANGLES / TO ORIENTATION
Just to add to the pile of solutions give than haven’t worked, I was suggested on using:

This didn’t work as it gave me the X and Z, which is not what I wanted, only the angle.

Any way to solve this would be greatly appreciated!

I added a green vector that has a different length but same direction as the hypotenuse / span of the plane. It’s clear from the drawing that it has the same angle. So any vector that has the same direction as the plane will do. The perfect vector for this is its LookVector. This will also work no matter what pitch, yaw or roll the plane has, so in all situations. Except maybe if the plane is upside down? Depends which angle you’d want in that situation.

I also added the purple UpVector to the drawing to illustrate why your first attempt wouldn’t have worked - you’re trying to get the angle between two vectors that are always going to be perpendicular, so that can’t be the right solution. And an orange arrow that represents “horizontal”, or “no pitch / aoe”). This is going to change with the yaw, so we have to get it from the CFrame of the plane.

Anyway, here’s how you get the angle:

local elevation_angle
local facing = Platform.CFrame.LookVector
local horizontal_facing = (facing * Vector3.new(1, 0, 1)) --Remove the vertical component
if horizontal_facing.Magnitude == 0 then
--If the plane is straight up/down, handle degenerative cases
if facing.Y > 0 then
elevation_angle = math.pi/2
else
elevation_angle = -math.pi/2
end
else
elevation_angle = math.acos( facing:Dot(horizontal_facing) )
end

It’s really a one-liner at the bottom of the code, but I included some logic for checking if the plane is going straight up/down, in which case horizontal_facing would be (0, 0, 0), and facing:Dot(horizontal_facing) would be undefined and the elevation_angle would be NaN because of division with 0 IIRC.