Im making a 3d platrformer game, and i want add a climbing system. But all tutorials working buggy with animation glitches or working for all blocks:
EXAMPLE OF ONE CODE FROM TUTORIALS:
local wall = nil
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local anim = script.Parent:WaitForChild("Humanoid"):LoadAnimation(script.Parent:WaitForChild("Animate").climb.ClimbAnim)
game:GetService("RunService").Heartbeat:Connect(function()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
local raycastResult = workspace:Raycast(script.Parent.LeftFoot.Position, hrp.CFrame.LookVector * 1.3, raycastParams)
wall = raycastResult and raycastResult.Instance or nil
if wall then
hrp.Velocity = Vector3.new(hrp.Velocity.X, 20, hrp.Velocity.Z)
if script.Parent.Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then script.Parent.Humanoid:ChangeState(Enum.HumanoidStateType.Climbing) end
if not anim.IsPlaying then anim:Play() end
else
anim:Stop()
end
end)
I have looked at your script, it is perfect but to do it you must use the CollectionService and tags, I suggest using TagEditor Plugin. Use this modified version of your script (In the CollectionService:GetTagged(“ClimbableWall”) put whatever your tag name is)!
Heres the script:
local CollectionService = game:GetService("CollectionService")
local wall = nil
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local anim = script.Parent:WaitForChild("Humanoid"):LoadAnimation(script.Parent:WaitForChild("Animate").climb.ClimbAnim)
game:GetService("RunService").Heartbeat:Connect(function()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
local raycastResult = workspace:Raycast(script.Parent.LeftFoot.Position, hrp.CFrame.LookVector raycastParams)
wall = raycastResult and raycastResult.Instance or nil
for i, Part in pairs(CollectionService:GetTagged("ClimbAbleWall")) do -- Put your tag instead ClimbAbleWall
if Part:IsA("BasePart") and wall ~= nil then
if raycastResult.Instance == Part then
wall = raycastResult and raycastResult.Instance or nil
else
wall = nil
end
end
end
if wall then
hrp.Velocity = Vector3.new(hrp.Velocity.X, 20, hrp.Velocity.Z)
if script.Parent.Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then script.Parent.Humanoid:ChangeState(Enum.HumanoidStateType.Climbing) end
if not anim.IsPlaying then anim:Play() end
else
anim:Stop()
end
end)
Does this help? I just added a few adjustments to your script.
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local anim = script.Parent:WaitForChild("Humanoid"):LoadAnimation(script.Parent:WaitForChild("Animate").climb.ClimbAnim)
game:GetService("RunService").Heartbeat:Connect(function()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
local raycastResult = workspace:Raycast(hrp.Position, hrp.CFrame.LookVector * 1.3, raycastParams)
if raycastResult and raycastResult.Instance:IsA("Part") then
hrp.Velocity = Vector3.new(hrp.Velocity.X, 20, hrp.Velocity.Z)
local humanoid = script.Parent.Humanoid
if humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
humanoid:Move(Vector3.new(0, 0, 0)) -- Stop other movement
humanoid:ChangeState(Enum.HumanoidStateType.Climbing)
end
if not anim.IsPlaying then
anim:Play()
end
else
anim:Stop()
end
end)