Hello, I copied and pasted an open source climb system and I made some changes like it always checks for walls instead of a desired key, but this causes a lot of lag.
I want to try improve the code so it’s not always shooting raycasts instead only when some condition is met.
I tried using humanoid.Running, but it didn’t really work so if there is any other possible way please suggest.
Code:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local climbAni = animator:LoadAnimation(script:WaitForChild("Climb R6"))
local speed = 10
local params = RaycastParams.new()
params.FilterDescendantsInstances = {character}
params.FilterType = Enum.RaycastFilterType.Exclude
local attach = Instance.new("Attachment")
attach.Parent = rootPart
local move = Instance.new("LinearVelocity")
move.Enabled = false
move.MaxForce = math.huge
move.Attachment0 = attach
move.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
move.VectorVelocity = Vector3.new()
move.Parent = attach
local gyro = Instance.new("AlignOrientation")
gyro.Enabled = false
gyro.Mode = Enum.OrientationAlignmentMode.OneAttachment
gyro.RigidityEnabled = true
gyro.Attachment0 = attach
gyro.Parent = attach
local result
local canClimb = true
local XAxis = {
0; --Left
0 --Right
}
local YAxis = {
0; --Up
0 --Down
}
function down(KEY)
return UserInputService:IsKeyDown(Enum.KeyCode[KEY])
end
local function playAnimation()
if move.VectorVelocity ~= Vector3.new(0, 0, 0) and result then
climbAni:AdjustSpeed(1)
elseif result then
climbAni:AdjustSpeed(0)
end
end
RunService.Heartbeat:Connect(function()
if canClimb and result ~= nil then
if rootPart.Position.Y >= result.Instance.Position.Y + result.Instance.Size.Y/2 or rootPart.Position.Y <= 2 then
canClimb = false
rootPart.CFrame += rootPart.CFrame.LookVector+rootPart.CFrame.UpVector*2
end
local sideOrigin = rootPart.Position + rootPart.CFrame.LookVector
local sideDirection = (down("D") and -rootPart.CFrame.RightVector) or rootPart.CFrame.RightVector
local hit = workspace:Raycast(sideOrigin, sideDirection, params)
if hit then
gyro.CFrame = CFrame.lookAt(hit.Position+(hit.Normal/2), hit.Position)
rootPart.CFrame = CFrame.lookAt(hit.Position+(hit.Normal/2), hit.Position)
end
end
end)
do
local inputTask = {
[Enum.KeyCode.W] = function(state)
YAxis[1] = (state and 1) or 0
end;
[Enum.KeyCode.S] = function(state)
YAxis[2] = (state and 1) or 0
end;
[Enum.KeyCode.A] = function(state)
XAxis[1] = (state and 1) or 0
end;
[Enum.KeyCode.D] = function(state)
XAxis[2] = (state and 1) or 0
end;
[Enum.KeyCode.Space] = function(state)
if state then
canClimb = false
end
end;
}
UserInputService.InputBegan:Connect(function(input: InputObject)
if inputTask[input.KeyCode] then
inputTask[input.KeyCode](true)
end
end)
UserInputService.InputEnded:Connect(function(input: InputObject)
if inputTask[input.KeyCode] then
inputTask[input.KeyCode](false)
end
end)
end
RunService.Stepped:Connect(function()
local origin = rootPart.Position
local direction = rootPart.CFrame.LookVector
result = workspace:Raycast(origin, direction, params)
if result and canClimb and result.Instance:GetAttribute("Climbable") then
humanoid.AutoRotate = false
humanoid.PlatformStand = true
gyro.CFrame = CFrame.lookAt(result.Position + (result.Normal/2), result.Position)
move.Enabled = true
gyro.Enabled = true
if not climbAni.IsPlaying then
climbAni:Play()
end
local X = XAxis[2]-XAxis[1]
local Y = YAxis[1]-YAxis[2]
move.VectorVelocity = Vector3.new(X*speed, Y*speed, 0)
playAnimation()
elseif not canClimb and move.Enabled == true then
humanoid.AutoRotate = true
humanoid.PlatformStand = false
move.Enabled = false
gyro.Enabled = false
result = nil
climbAni:Stop()
task.wait(0.5)
canClimb = true
end
end)
Thank you.