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)
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.
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!