Above is the same image, but the red points are what I want to get. Since I rotated the object with the blue dash on it to its side, it doesn’t get the red surface position anymore. It instead gets the position of the blue dot.
To be as simple as possible, I want to get the top surface position (the red marks) of all the parts regardless of the parts orientation. I know this is possible with UpVector but I don’t understand CFrame in the slightest.
This is the math I currently have for getting the surface position. It works perfectly for parts until they’re rotated.
local TopSurfaceYAxis = (BasePart.CFrame * CFrame.new(0, BasePart.Size.Y / 2, 0))
I think probably the easiest way to do this would be to loop through each face and track which one had the highest y-value.
--TopSurfaceYAxis's y-value must be set to -math.huge so rotated normals under 0 work
local TopSurfaceYAxis, CFHold = CFrame.new(0, -math.huge, 0), CFrame.new()
for _, face in pairs(Enum.NormalId:GetEnumItems()) do
--get the rotated normal
CFHold = BasePart.CFrame * CFrame.new(Vector3.fromNormalId(face) * BasePart.Size / 2)
--compare the rotated normal's y-value to current y-value
if CFHold.p.Y > TopSurfaceYAxis.p.Y then
TopSurfaceYAxis = CFHold
end
end
This could be improved, i.e. using a direction Vector and getting the angle between that and each normal, but for simplicity’s sake I think this is fine.
From my knowledge, no. CFrame.UpVector returns the up-facing direction of the CFrame, which accounts for rotation. In a problem like this where the CFrame is arbitrarily rotated, UpVector doesn’t give any useful information.
Make sure all your parts are rotated the correct way(easiest and simplist to do)
Raycast above the part downwards then find the matching face by comparing it with the CFrame of the part(relatively simple but not really effective and not recommended for a task like this)
Use maths. Get the DotProduct of every Vector to the world’s up vector( which is (0,1,0) then the Smallest product will be the one that faces upwards the most.
Or you can do the other method @ranto828 said, testing to see which side of the part is higher although it will not work for long and flat parts.
(You will need a map for getting the normal corresponding to each face.)
Thank you both for the information. I’ve decided to use ranto’s method as well as incorporate a small amount of raycasting just for double checking to get long and flat parts.