Hello there.
I began thinking about how to create a proper ledge climb script, however, I got some problems with it.
If I try to ledge on the other sides of that wall, however, the rotation will be weird and the character won't face the wall like on the first image
Also when I rotate my camera in first person, it rotates the entire avatar, despite the HumanoidRootPart being anchored
If you spot any problems in the script attached below, please let me know. Thank you for your time!
local plr = game.Players.LocalPlayer
local Character = plr.Character or plr.CharacterAdded:Wait()
local Root = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")
local Humanoid = Character:WaitForChild("Humanoid")
local CA = Humanoid:LoadAnimation(script:WaitForChild("ClimbAnim"))
local HA = Humanoid:LoadAnimation(script:WaitForChild("HoldAnim"))
local TouchGui = plr:WaitForChild("PlayerGui"):FindFirstChild("TouchGui")
local UIS = game:GetService("UserInputService")
local ledgeAvailable = true -- can you ledge or not
local isHolding = false -- is ledging or not
local ledgeDeb = false -- ledge debounce
local isClimbing = false -- is climbing or not
local function detachFromLedge()
Root.Anchored = false
isHolding = false
isClimbing = false
HA:Stop()
CA:Stop()
end
local function climb()
local velocity = Instance.new("BodyVelocity", Root)
velocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
velocity.Velocity = Root.CFrame.LookVector * 10 + Vector3.new(0, 40, 0)
isHolding = false
CA:Play()
HA:Stop()
Root.Anchored = false
game.Debris:AddItem(velocity, .15)
isClimbing = true
end
UIS.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if not isHolding then return end
if input.KeyCode == Enum.KeyCode.Space then
climb()
end
end)
while wait() do
local ray = Ray.new(Head.CFrame.p, Head.CFrame.LookVector * 5)
local part, position = workspace:FindPartOnRay(ray, Character)
if part and ledgeAvailable and not isHolding then
if part.Size.Y >= 7 then
local ledgeYPos = part.Position.Y + (part.Size.Y / 2)
local headYPos = Head.Position.Y
local isHeadWithinLedgeYPos = headYPos >= ledgeYPos - 1 and headYPos <= ledgeYPos
if isHeadWithinLedgeYPos and Humanoid.FloorMaterial == Enum.Material.Air and Root.Velocity.Y <= 0 then
Root.Anchored = true
isHolding = true
HA:Play()
ledgeAvailable = false
end
end
end
if isHolding and not isClimbing and not ledgeDeb then
Root.CFrame = CFrame.new(position) * CFrame.new(0, -1.5, 0) * CFrame.Angles(0, -math.pi, 0)
ledgeDeb = true
end
if isClimbing and CA.IsPlaying == false then
detachFromLedge()
ledgeAvailable = true
ledgeDeb = false
end
end