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.