My issue is when I let go of space early/before the wallclimbing ends I can’t wallclimb a second time, but if I let it finish I can.
video:
local script:
local c = script.Parent
local holdingKey = false
local wallrunCount = 1
local wallrunDuration = 1
local wallrunTimer = 0
local maxWallruns = 2
local fallThreshold = 3
local canWallclimb = true
local UIS = game:GetService("UserInputService")
local ClimbAnim = c.Humanoid:LoadAnimation(script:WaitForChild("ClimbAnim"))
local WallClimbSound = game.ReplicatedStorage.Sounds.WallclimbSound
local plr = game.Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")
local initialWalkSpeed = 0
local targetWalkSpeed = 10
local accelerationRate = (targetWalkSpeed - initialWalkSpeed) / wallrunDuration
local originalWalkSpeed = c.Humanoid.WalkSpeed
plr:SetAttribute("WallClimbing", false)
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.KeyCode == Enum.KeyCode.Space then
if not holdingKey and canWallclimb and wallrunCount < maxWallruns then
holdingKey = true
wallrunTimer = 0
canWallclimb = false
originalWalkSpeed = c.Humanoid.WalkSpeed
end
end
end)
UIS.InputEnded:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.KeyCode == Enum.KeyCode.Space then
holdingKey = false
end
end)
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent and (input.KeyCode ~= Enum.KeyCode.ButtonA) then return end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonA then
if not holdingKey and canWallclimb and wallrunCount < maxWallruns then
holdingKey = true
wallrunTimer = 0
canWallclimb = false
originalWalkSpeed = c.Humanoid.WalkSpeed
end
end
end
end)
UIS.InputEnded:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent and (input.KeyCode ~= Enum.KeyCode.ButtonA) then return end
if input.UserInputType == Enum.UserInputType.Gamepad1 then
if input.KeyCode == Enum.KeyCode.ButtonA then
holdingKey = false
end
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {c}
raycastParams.IgnoreWater = true
local rayUp = workspace:Raycast(c.HumanoidRootPart.Position, c.HumanoidRootPart.CFrame.LookVector * 3, raycastParams)
local rayDown = workspace:Raycast(c.HumanoidRootPart.Position, -c.HumanoidRootPart.CFrame.UpVector * fallThreshold, raycastParams)
local ray = rayUp
if rayDown and not ray and not canWallclimb then
canWallclimb = true
end
if ray and holdingKey and not canWallclimb then
if not ClimbAnim.IsPlaying then
ClimbAnim:Play()
plr:SetAttribute("WallClimbing", true)
end
local currentWalkSpeed = c.Humanoid.WalkSpeed
if currentWalkSpeed < targetWalkSpeed then
currentWalkSpeed = math.min(currentWalkSpeed + accelerationRate * deltaTime, targetWalkSpeed)
c.Humanoid.WalkSpeed = currentWalkSpeed
end
wallrunTimer = wallrunTimer + deltaTime
local part = ray.Instance
local weld = c.HumanoidRootPart:FindFirstChild("WallrunWeld") or Instance.new("WeldConstraint")
weld.Name = "WallrunWeld"
weld.Part0 = c.HumanoidRootPart
weld.Part1 = part
local bp = c.HumanoidRootPart:FindFirstChild("WallrunBodyPosition") or Instance.new("BodyPosition", c.HumanoidRootPart)
bp.Name = "WallrunBodyPosition"
bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bp.Position = c.HumanoidRootPart.Position + c.HumanoidRootPart.CFrame.UpVector * c.Humanoid.WalkSpeed / 3
if wallrunTimer >= wallrunDuration then
holdingKey = false
wallrunCount = wallrunCount + 1
if wallrunCount >= maxWallruns then
wallrunCount = 0
canWallclimb = true
end
end
if not WallClimbSound.IsPlaying then
WallClimbSound:Play()
end
else
for i, child in pairs(c.HumanoidRootPart:GetChildren()) do
if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" then
c.Humanoid.WalkSpeed = originalWalkSpeed
child:Destroy()
end
end
plr:SetAttribute("WallClimbing", false)
ClimbAnim:Stop()
wallrunTimer = 0
if WallClimbSound.IsPlaying then
WallClimbSound:Stop()
end
end
end)
Seems like a lot of trouble to climb … could just add an invisible TrussParts part in the wall.
Don’t know what you’re all doing so here is a script, I hope it works out.
Script
local c = script.Parent
local holdingKey = false
local wallrunCount = 1
local wallrunDuration = 1
local wallrunTimer = 0
local maxWallruns = 2
local fallThreshold = 3
local canWallclimb = true
local UIS = game:GetService("UserInputService")
local ClimbAnim = c.Humanoid:LoadAnimation(script:WaitForChild("ClimbAnim"))
local WallClimbSound = game.ReplicatedStorage.Sounds.WallclimbSound
local plr = game.Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")
local initialWalkSpeed = 0
local targetWalkSpeed = 10
local accelerationRate = (targetWalkSpeed - initialWalkSpeed) / wallrunDuration
local originalWalkSpeed = c.Humanoid.WalkSpeed
plr:SetAttribute("WallClimbing", false)
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent or holdingKey or not canWallclimb or wallrunCount >= maxWallruns then return end
if input.KeyCode == Enum.KeyCode.Space or (input.KeyCode == Enum.KeyCode.ButtonA and input.UserInputType == Enum.UserInputType.Gamepad1) then
holdingKey = true
wallrunTimer = 0
canWallclimb = false
originalWalkSpeed = c.Humanoid.WalkSpeed
end
end)
UIS.InputEnded:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent or not holdingKey then return end
if input.KeyCode == Enum.KeyCode.Space or (input.KeyCode == Enum.KeyCode.ButtonA and input.UserInputType == Enum.UserInputType.Gamepad1) then
holdingKey = false
end
end)
game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {c}
raycastParams.IgnoreWater = true
local rayUp = workspace:Raycast(c.HumanoidRootPart.Position, c.HumanoidRootPart.CFrame.LookVector * 3, raycastParams)
local rayDown = workspace:Raycast(c.HumanoidRootPart.Position, -c.HumanoidRootPart.CFrame.UpVector * fallThreshold, raycastParams)
local ray = rayUp
if rayDown and not ray and not canWallclimb then
canWallclimb = true
end
if ray and holdingKey and not canWallclimb then
if not ClimbAnim.IsPlaying then
ClimbAnim:Play()
plr:SetAttribute("WallClimbing", true)
end
local currentWalkSpeed = c.Humanoid.WalkSpeed
if currentWalkSpeed < targetWalkSpeed then
currentWalkSpeed = math.min(currentWalkSpeed + accelerationRate * deltaTime, targetWalkSpeed)
c.Humanoid.WalkSpeed = currentWalkSpeed
end
wallrunTimer = wallrunTimer + deltaTime
local part = ray.Instance
local weld = c.HumanoidRootPart:FindFirstChild("WallrunWeld") or Instance.new("WeldConstraint")
weld.Name = "WallrunWeld"
weld.Part0 = c.HumanoidRootPart
weld.Part1 = part
local bp = c.HumanoidRootPart:FindFirstChild("WallrunBodyPosition") or Instance.new("BodyPosition", c.HumanoidRootPart)
bp.Name = "WallrunBodyPosition"
bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bp.Position = c.HumanoidRootPart.Position + c.HumanoidRootPart.CFrame.UpVector * c.Humanoid.WalkSpeed / 3
if wallrunTimer >= wallrunDuration then
holdingKey = false
wallrunCount = wallrunCount + 1
if wallrunCount >= maxWallruns then
wallrunCount = 0
canWallclimb = true
end
end
if not WallClimbSound.IsPlaying then
WallClimbSound:Play()
end
else
for i, child in pairs(c.HumanoidRootPart:GetChildren()) do
if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" then
c.Humanoid.WalkSpeed = originalWalkSpeed
child:Destroy()
end
end
plr:SetAttribute("WallClimbing", false)
ClimbAnim:Stop()
wallrunTimer = 0
if WallClimbSound.IsPlaying then
WallClimbSound:Stop()
end
end
end)
Ok so there’s a few things to digest here, your lack of comments makes your script quite hard to follow/understand what different t variables and conditions mean, I’d recommend going through and commenting each line where you think it’d be important to know what’s going on.
Secondly your use of the variable canWallClimb is quite confusing to me. It seems like your using the false value to tell the script that you wanna climb instead of vice versa. Evident in the condition “and not canWallClimb” then… Wall climb function. So have another look at that because there’s a good chance you might have messed up with how this might be set.
There seems to be a lot of instances in your code that are counterintuitive. You have a condition to check if the wall is within 3 studs Infront of the HRP yet you set canWallClimb to true if this condition is not met.
I think you’d be best to go through your code and clean it up a bit to help in your debugging process, also use prints to find out where it’s going wrong.