I currently have a parkour system that I would like to make smoother. When grabbing onto ledges it snaps into place rather than smoothly positioning. I have tried tweens but they didn’t help very much.
-- Server code
local Events_And_Functions = game:GetService("ReplicatedStorage"):WaitForChild("Events/Funcions")
local ParkourEvents = Events_And_Functions:WaitForChild("Parkour")
local LedgeFunction = ParkourEvents:WaitForChild("GrabLedge")
local GrabPartName = "GrabPart"
function ClosestLedge(Character)
local Ledges = {}
local Root = Character.HumanoidRootPart.Position
local Closest = nil
for _,v in pairs(workspace:GetDescendants()) do
if v.Name == "GrabPartName" or v:FindFirstChild("IsLedge") then
if Closest == nil then
Closest = v
else
if (Root - v.Position).magnitude < (Closest.Position - Root).magnitude then
Closest = v
end
end
end
end
return Closest
end
function isInsideBrick(position, brick)
local v3 = brick.CFrame:PointToObjectSpace(position)
return (math.abs(v3.X) <= brick.Size.X / 2)
and (math.abs(v3.Y) <= brick.Size.Y / 2)
and (math.abs(v3.Z) <= brick.Size.Z / 2)
end
function GrabLedge(Player,Grab,Drop)
local Character = Player.Character
if Grab == true then
local Ledge = ClosestLedge(Character)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {Character}
raycastParams.IgnoreWater = true
local Offset = Character.HumanoidRootPart.CFrame:ToObjectSpace(Ledge.CFrame)
local Origin = (Ledge.CFrame * CFrame.new(Offset.X,0,-Offset.Z)).Position
local RayDirection = -(Character.HumanoidRootPart.CFrame * CFrame.new(0,Origin.Y,0)).LookVector * 3
local raycastResult = workspace:Raycast(Origin, RayDirection, raycastParams)
if raycastResult then
local Distance = (raycastResult.Position - Character.Head.Position).Magnitude
if Distance <= 3 then
Character.Humanoid.PlatformStand = true
Character.HumanoidRootPart.Anchored = true
workspace.Part2.CFrame = CFrame.new(raycastResult.Position) * CFrame.new(0.02,0,0) * CFrame.Angles(0,math.rad(Ledge.Orientation.Y),0)
Character.HumanoidRootPart.CFrame = (CFrame.new(raycastResult.Position) * CFrame.Angles(0,math.rad(Ledge.Orientation.Y)+math.rad(180),0)) * CFrame.new(0,-0.75,2.5)
return true
else
return false
end
else
return false
end
else
Character.HumanoidRootPart.Anchored = false
Character.Humanoid.PlatformStand = false
wait()
if not Drop then
Character.HumanoidRootPart.Velocity = Vector3.new(0,50,0)
end
end
end
LedgeFunction.OnServerInvoke = GrabLedge
-- Client Code
local UIS = game:GetService("UserInputService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events_And_Functions = ReplicatedStorage:WaitForChild("Events/Funcions")
local AnimationsFolder = ReplicatedStorage:WaitForChild("Animations")
local GrabAnim = Character:WaitForChild("Humanoid"):LoadAnimation(AnimationsFolder.GrabAnim)
local ParkourEvents = Events_And_Functions:WaitForChild("Parkour")
local LedgeFunction = ParkourEvents:WaitForChild("GrabLedge")
local HoldingSpace = false
local GrabbingLedge = false
local GrabCooldown = false
local GrabCooldownTime = 0.3
function LetGoOfLedge(Grab,Drop)
GrabCooldown = true
GrabAnim:Stop()
LedgeFunction:InvokeServer(Grab,Drop)
GrabbingLedge = false
wait(GrabCooldownTime)
GrabCooldown = false
end
UIS.InputBegan:Connect(function(IO,GPE)
if not GPE then
if IO.KeyCode == Enum.KeyCode.Space then
if not GrabbingLedge and not GrabCooldown then
for i = 1,20 do
wait(0.1)
if UIS:IsKeyDown(Enum.KeyCode.Space) and LedgeFunction:InvokeServer(true) == true then
GrabbingLedge = true
GrabAnim:Play()
return
end
end
else
LetGoOfLedge(false,false)
end
elseif IO.KeyCode == Enum.KeyCode.C then
LetGoOfLedge(false,true)
end
end
end)
Any feedback is greatly appreciated!