Finding the upper ledges of a part

I’m trying to calculate the upper ledges of a part (for dynamic parkour instead of node based).
So far I’ve been able to find all edges of a part and check which ones are horizontal for climbing.
After drawing all the edges of the part, i’m also able to find the closest point to the character on each edge.
But, I’m unsure of how I would differentiate between an actual ledge (an upper edge) and a bottom edge (it wouldn’t make sense to be able to climb the bottom edge of a part).

My ledge calculation so far:

local function findClosestPointOnSegment(point,startp,endp)

	local segment = Ray.new(startp,((endp-startp).unit) * ((endp-startp).Magnitude))
	return segment:ClosestPoint(point) 

end

local function findClosestUpperHorizontalEdgePoint(part,point)
	
	if part:IsA'Part' and part.Shape == Enum.PartType.Block then --if regular part (rectangular prism)
		
		local centerPos = part.CFrame
		local Size = part.Size
		
		local corner1 = centerPos*CFrame.new(Size/2)
		
		local corner2 = centerPos*CFrame.new(Size.X/2 , Size.Y/2 , -Size.Z/2)
		
		local corner3 = centerPos*CFrame.new(-Size.X/2, Size.Y/2, -Size.Z/2)
		
		local corner4 = centerPos*CFrame.new(-Size.X/2, Size.Y/2, Size.Z/2)
		
		local corner5 = centerPos*CFrame.new(Size.X/2 , -Size.Y/2 , Size.Z/2)
		
		local corner6 = centerPos*CFrame.new(Size.X/2 , -Size.Y/2 , -Size.Z/2)
		
		local corner7 = centerPos*CFrame.new(-Size/2)
		
		local corner8 = centerPos*CFrame.new(-Size.X/2 , -Size.Y/2 , Size.Z/2)
		
		
		
		local Corners = {corner1,corner2,corner3,corner4,corner5,corner6,corner7,corner8}
		
		
		local closestUpperHorizontalEdges = {}
		
		for i,v in pairs(Corners) do --Draw each edge from a list of corners
			
			if i < 4 then
				if (v.p-Corners[i+1].p).unit.Y >= -.333 and (v.p-Corners[i+1].p).unit.Y <= .333 then --Check the direction of the edge, if it's too far from being horizontal, ignore it.
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[i+1].p))
				end
				
			elseif i == 4 then
				if (v.p-Corners[1].p).unit.Y >= -.333 and (v.p-Corners[1].p).unit.Y <= .333 then
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[1].p))
				end
				
			elseif i < 8 then
				if (v.p-Corners[i+1].p).unit.Y >= -.333 and (v.p-Corners[i+1].p).unit.Y <= .333 then
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[i+1].p))
				end
				if (v.p-Corners[i-4].p).unit.Y >= -.333 and (v.p-Corners[i-4].p).unit.Y <= .333 then
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[i-4].p))
				end
				
			elseif i == 8 then
				if (v.p-Corners[i-3].p).unit.Y >= -.333 and (v.p-Corners[i-3].p).unit.Y <= .333 then
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[i-3].p))
				end
				if (v.p-Corners[i-4].p).unit.Y >= -.333 and (v.p-Corners[i-4].p).unit.Y <= .333 then
					table.insert(closestUpperHorizontalEdges,findClosestPointOnSegment(point,v.p,Corners[i-4].p))
				end
				
			end
			
		end
		
		local closestPoint = closestUpperHorizontalEdges[1]
		local closestDist = (point - closestUpperHorizontalEdges[1]).Magnitude
		
		for i,v in pairs(closestUpperHorizontalEdges) do
			print((point-v).magnitude)
		end
		
		print(#closestUpperHorizontalEdges..' nearby horizontal edges found')
		
		
		
		
		
	elseif part:IsA'Part' and part.Shape == Enum.PartType.Cylinder then --if cylinder
		
		
	elseif part:IsA'WedgePart' then --if triangular prism
		
	
		
	end
	
end


Hopefully this picture clearly shows what edges of a part i’m trying to find.

1 Like

Couldn’t you just check which point/s have the highest Y and go with that?

If you are dealing with a rectangular box I believe the CFrame Position of the center of each edge that is climbable is higher than the CFrame Position of the box itself, the rest are your red edges.
Maybe subtract a small percentage difference between the two so almost vertical edges don’t become climbable too.

3 Likes

Oh what a coincedence, happy birth day.

1 Like

couldnt you just make the blocks out of multiple different blocks and name the lower parts of the block “lowerparts” for example i think this would simplifiy things

happy birthday @MagikTheDog

2 Likes