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