You can write your topic however you want, but you need to answer these questions:
-
I Have a climbing system but ive encountered an issue
-
When i double tap the Spacebar instead of holding it, the character seems to drift away
-
I tried setting up debounces but it didnt seem to work, probably a skill issue from me
here’s my full code if needed
-- // Services \\ --
local UIS = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
-- // Local Player & Character Variables \\ --
local localPlr = Players.LocalPlayer
local character = localPlr.Character or localPlr.CharacterAdded:Wait()
local HRP = character:WaitForChild("HumanoidRootPart")
local Hum = character:WaitForChild("Humanoid")
local head = character:WaitForChild("Head")
local ClimbAnimation = Instance.new("Animation")
ClimbAnimation.AnimationId = "rbxassetid://115706581497213"
local Climb = Hum.Animator:LoadAnimation(ClimbAnimation)
Climb.Priority = Enum.AnimationPriority.Action2
local GrabAnimation = Instance.new("Animation")
GrabAnimation.AnimationId = "rbxassetid://122583292148993"
local Grab = Hum.Animator:LoadAnimation(GrabAnimation)
Grab.Priority = Enum.AnimationPriority.Action2
-- Climbing Constants
local MaxUpwardsVel = 30
local ClimbDuration = 1 -- Time to decrease upward velocity to 0
local MaxDistance = 10
local CD = 0.5
-- Climbing State variables
local isClimbing = false
local climbStartTime = 0
local Vel = nil
local UpwardsVel = MaxUpwardsVel
local climbingSurface = nil
local canClimbAgain = true
local isLadder = false
-----------Debug-------------------
local spaceHeld = false
local spacePressedThisFrame = false
local spaceConsumed = false
local lastClimbStart = 0
local CLIMB_INPUT_COOLDOWN = 0.15
-- Climbing logic
local function stopClimbing()
if isClimbing then
isClimbing = false
canClimbAgain = false
isLadder = false
if Climb.IsPlaying then
Climb:Stop()
end
if Vel then
Vel:Destroy()
Vel = nil
end
climbingSurface = nil
end
end
-- Ledge grabbing logic
local function LedgeGrab()
if isClimbing then
isClimbing = false
canClimbAgain = false
if Climb.IsPlaying then
Climb:Stop()
end
if Vel then
Vel:Destroy()
Vel = nil
end
climbingSurface = nil
end
Grab:Play()
local newVel = Instance.new("BodyVelocity")
newVel.Name = "Hello"
newVel.Parent = HRP
newVel.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
newVel.Velocity = Vector3.new(0, 35, 0) + HRP.CFrame.lookVector * 20
task.wait(0.1)
newVel:Destroy()
print("Works")
end
----------------------------------------
local function startClimbing(hitPart, hitPosition, hitNormal)
if isClimbing or not canClimbAgain then return end
isClimbing = true
climbStartTime = tick()
UpwardsVel = MaxUpwardsVel
climbingSurface = hitPart
isLadder = hitPart:GetAttribute("Ladder") == true
-- Snap character to the climbing surface
local offset = hitNormal * (character.HumanoidRootPart.Size.Z / 2 + 1.5)
local newPosition = hitPosition + offset
local Properties = { CFrame = CFrame.new(newPosition, newPosition - hitNormal) }
local Info = TweenInfo.new(0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local T = game:GetService("TweenService"):Create(HRP, Info, Properties)
T:Play()
T.Completed:Wait()
HRP.CFrame = CFrame.new(newPosition, newPosition - hitNormal)
Vel = Instance.new("BodyVelocity")
Vel.Parent = HRP
Vel.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
Vel.Velocity = Vector3.new(0, UpwardsVel, 0)
Climb:Play()
end
--Update climb velocity
local function updateIntermittentVelocity()
if isClimbing and Vel then
-- LADDER: no decay, no limit
if isLadder then
Vel.Velocity = Vector3.new(0, MaxUpwardsVel, 0)
Climb:AdjustSpeed(1)
return
end
-- NORMAL WALL: decay over time
local elapsedTime = tick() - climbStartTime
local progress = math.min(elapsedTime / ClimbDuration, 1)
UpwardsVel = MaxUpwardsVel * (1 - progress)
Vel.Velocity = Vector3.new(0, UpwardsVel, 0)
Climb:AdjustSpeed(UpwardsVel / MaxUpwardsVel)
if progress >= 1 then
stopClimbing()
end
end
end
Hum.StateChanged:Connect(function(_, newState)
if newState == Enum.HumanoidStateType.Landed then
wait(CD)
canClimbAgain = true
end
end)
-- Check climbing conditions
local function canClimb()
local BodyRayOrigin = HRP.Position + Vector3.new(0, 0, 0) -- Slightly below HumanoidRootPart for body detection.
local HeadRayOrigin = head.Position + Vector3.new(0, 2.5, 0) -- Slightly above the head for ledge detection.
local NeckRayOrigin = head.Position + Vector3.new(0,-1,0)
local RayDirection = HRP.CFrame.LookVector * (MaxDistance)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
raycastParams.IgnoreWater = true
local BodyRaycastResult = workspace:Raycast(BodyRayOrigin, RayDirection, raycastParams)
local HeadRaycastResult = workspace:Raycast(HeadRayOrigin, RayDirection, raycastParams)
local NeckRaycastResult = workspace:Raycast(NeckRayOrigin, RayDirection, raycastParams)
if BodyRaycastResult and HeadRaycastResult and NeckRaycastResult then
return true, false, BodyRaycastResult.Instance, BodyRaycastResult.Position, BodyRaycastResult.Normal
elseif BodyRaycastResult and not HeadRaycastResult then
return false, true, BodyRaycastResult.Instance, BodyRaycastResult.Position, BodyRaycastResult.Normal
end
return false, false
end
RunService:BindToRenderStep("Climbing", Enum.RenderPriority.Input.Value, function()
local canClimbResult, canLedgeGrab, hitPart, hitPosition, hitNormal = canClimb()
local spaceHeld = UIS:IsKeyDown(Enum.KeyCode.Space)
-- Space released makes stop
if not spaceHeld and isClimbing then
stopClimbing()
return
end
-- Start climbing
if spaceHeld
and canClimbResult
and canClimbAgain
and hitPart:IsA("Part")
and hitPart:GetAttribute("CantBeClimbed") == nil
and not isClimbing
then
startClimbing(hitPart, hitPosition, hitNormal)
-- Ledge grab
elseif spaceHeld
and canLedgeGrab
and not canClimbResult
and isClimbing
then
LedgeGrab()
end
updateIntermittentVelocity()
end)
character.AncestryChanged:Connect(function(_, parent)
if not parent then
stopClimbing()
end
end)
I will aslo provide a video, at first i simply held the spacebar, then i pressed the spacebar twice quickly
Please help i cant find a proper solution!!