How can I detect where a parts ledge is?

I need a way to find where a parts ledge is so the player can ledge grab. For now I’m just using an invisible block.

Heres my code:


UIS.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	
	if input.KeyCode == Enum.KeyCode.Space then
		local distance = (hrp.Position - ledge.Position).magnitude
		if  distance < 2 then
			print('Player has ledge grabbed!')
			hrp.Anchored = true
		end
		
	end
	
end)

UIS.InputEnded:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.S then
		print('Player has stopped ledge grabbing!')
		hrp.Anchored = false
	end
end)

Launch a ray cast down by X amount over the entire part then if there is nothing underneath it it is a ledge

2 Likes

What do you mean by nothing underneath it? Also launch a raycast down by what amount?

1 Like

If it is a ledge then there would be empty space below it:

image

2 Likes

For the amount it would probably be anything below or equal to 1

1 Like

I’ve made something similar. The same structure might work for you.

RunService:BindToRenderStep():

  • Bind a function here that casts a ray from the character’s HumanoidRootPart and the character’s Head. If the RootPart ray hits and the head one does not, they are at a ledge.
  • Then, cast a ray downwards from slightly further in front of the hit position of the RootPart ray. If it hits, they are 100% at a ledge.
1 Like

As someone who hasn’t used Raycast much at all, how would this work? What would you send the rays toward if the ledge is unkown?

(Are rays able to be used without directional inputs?)

1 Like

You don’t need inputs for rays. Here are the three parameters workspace:Raycast takes:

  • Origin (required) - A Vector3 position where the ray will begin.
  • Direction (required) - A Vector3 position controlling the ray’s direction and length.
  • RaycastParams (optional) - An object that helps control the ray’s properties.

An example might be:

local runService = game:GetService("RunService")

local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

local hrp = char:WaitForChild("HumanoidRootPart")
local head = char:WaitForChild("Head")

--setting up RaycastParams
local params = RaycastParams.new()
params.FilterDescendantsInstances = char:GetDescendants()
params.FilterType = Enum.RaycastFilterType.Exclude
params.IgnoreWater = false
params.RespectCanCollide = true

local function cast()
    --origin (starting point)
    local rootOrigin = hrp.CFrame.Position
    local headOrigin = head.CFrame.Position
    
    --direction
    local rootDirection = hrp.CFrame.LookVector * 5
    local headDirection = head.CFrame.LookVector * 5
    
    --casting the rays
    local rootResult = workspace:Raycast(rootOrigin, rootDirection, params)
    local headResult = workspace:Raycast(headOrigin, headDirection, params)

    --check for wanted results
    if rootResult and not headResult then
        --The player is facing a ledge. You can get the position.
        print("Ledge: Ray hit at "..tostring(rootResult.Position))
    end
end

runService:BindToRenderStep("CheckLedge", 2000, cast) --Invoke the procedure every frame

The above script should detect when a player is facing a ledge. Hope this helps!

Also, here’s the documentation:
Raycasting | Documentation - Roblox Creator Hub

2 Likes

This does help me and it looks like it would do exactly what OP is asking. Thank you!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.