How can I improve this ledge climbing script?

parkour_test.rbxl (38.1 KB)

The script is supposed to make it so that when you press space near a ledge, your character will climb over it.
I’m not satisfied with how inconsistent the climbing is (sometimes it launches you over)

If you have any feedback or suggestions please let me know.

I do plan to add animations, I’m just too lazy to.

Parkour Script located in StarterCharacterScripts:

local character:Model = script.Parent

local humanoid:Humanoid = script.Parent:WaitForChild("Humanoid")
local humanoidRootPart:Part = script.Parent:WaitForChild("HumanoidRootPart")

local userInputService = game:GetService("UserInputService")
local debris = game:GetService("Debris")

local raycastDistance = 2
local force = Vector3.new(0, 5, -3) * 1000
local forceTime = 0.02
local climbHeight = 3

local gravity = workspace.Gravity

userInputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.Space and not gameProcessed then
		local raycastParams = RaycastParams.new()
		raycastParams.IgnoreWater = true
		raycastParams.FilterDescendantsInstances = {script.Parent}
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
		
		local raycastResult = workspace:Raycast(humanoidRootPart.Position, humanoidRootPart.CFrame.LookVector * 3000, raycastParams)
		
		if raycastResult then
			local position = raycastResult.Position
			local distance = (humanoidRootPart.Position - position).Magnitude
			if distance < raycastDistance then
				local part:Instance = raycastResult.Instance
				if part:IsA("BasePart") then
					local partPosition = part.Position
					local topOfPart = Vector3.new(position.X, part.Position.Y + part.Size.Y/2, position.Z)
					local topOfPartY = topOfPart.Y
					
					local heightDifference = math.abs(position.Y - topOfPartY)
					
					if heightDifference <= climbHeight or position.Y > topOfPartY then
						workspace.Gravity = 0
						
						humanoidRootPart.AssemblyLinearVelocity = Vector3.new()
						humanoidRootPart.AssemblyAngularVelocity = Vector3.new()
						
						local vectorForce = Instance.new("VectorForce")
						vectorForce.ApplyAtCenterOfMass = true
						vectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
						
						local attachment0 = Instance.new("Attachment")
						attachment0.Name = "Attachment0"
						attachment0.Parent = humanoidRootPart
						attachment0.CFrame = CFrame.new()
						attachment0.Position = Vector3.new()
						
						vectorForce.Attachment0 = attachment0
						
						local connection = game:GetService("RunService").RenderStepped:Connect(function()
							attachment0.WorldCFrame = CFrame.lookAt(humanoidRootPart.Position, topOfPart)
						end)
						
						local vectorForceY = vectorForce:Clone()
						vectorForceY.Force = Vector3.new(0, force.Y)
						vectorForceY.Parent = humanoidRootPart
						
						local vectorForceZ = vectorForce:Clone()
						vectorForceZ.Force = Vector3.new(0, 0, force.Z)
						vectorForceZ.Parent = humanoidRootPart
						
						workspace.Ball.Position = topOfPart
						
						spawn(function()
							print("Starting to delete: Y")
							repeat wait() until humanoidRootPart.Position.Y > (topOfPartY + 2)
							print("Y Deleted")
							debris:AddItem(vectorForceY, forceTime)
							vectorForceY = nil
						end)
						
						spawn(function()
							print("Starting to delete: Z")
							repeat wait() until not vectorForceY
							print("Z Deleted")
							debris:AddItem(vectorForceZ, forceTime)
						end)
						
						repeat wait() until not vectorForceY
						workspace.Gravity = gravity
					end
				end
			end
		end
	end
end)

I linked a .rbxl file if you want to go try out the climbing yourself.

Thanks!

2 Likes

try improving accuracy, its very hard for me to trigger it.

It is the raycast distance, try setting it to a higher number

found this, sorry for the fps