How to make any block climbable

Hello!

Title is pretty self explaining.
For example i want to climb flat wall, but i cant do this. What should i do?

4 Likes

I think changing your StarterPlayer’s MaxSlopeAngle to 90 should fix this.

1 Like

yea, or add truss to the wall and make them transparent, though its unpractical so i suggest using MaxSlopeAngle

2 Likes

Doesnt work

Note:
It cant be higher than 89.9

No? i dont want to put truss begind every single block

1 Like

You could try using raycasting to position a truss in front of the wall your character is facing, or code your own climbing logic

I mean you could just add some invisible parts hanging off the wall. It works, I’ve tried it before

Use a truss or fake a climb like this.

-- server script in StarterCharacterScripts

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)

Thanks to the tips here, I made a fake climb script that blocks Roblox climbing. Climb ONLY what you want. It only works for keyboard because I don’t have a touch device.
I’m good at coding, but I’m new to Roblox, so hopefully no mistakes were made. It has been designed and tested thoroughly.

--# Custom Fake Climb #--
-- A "fake climb" which only works on parts named "Climbable"
-- Native roblox climbing is blocked.
-- Climbing away from the wall horizontally will cause you to let go of it.

local UserInputService = game:GetService("UserInputService")

-- value is the speed of default gravity in steps (Precise but inexact. I found it myself.)
local GRAVITY_SPEED = 2.068633152040864

local RaycastLength = 2.2 -- length of the raycast that detects climbable parts.
local YAngle
local wall = nil
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Include
for _, part in pairs(game.Workspace:GetChildren()) do
	if string.find(part.Name,"Climbable") then -- The string is the name tag for climbable parts. Set it to whatever you want.
		params:AddToFilter(part)
	end
end

local chr = script.Parent
local hrp = chr:WaitForChild("HumanoidRootPart")
local hum = chr:WaitForChild("Humanoid")
local climbAnim = hum:LoadAnimation(chr:WaitForChild("Animate").climb.ClimbAnim)
local stopPos = nil


game:GetService("RunService").Heartbeat:Connect(function()
	local raycastResult = workspace:Raycast(chr.LeftFoot.Position,
		hrp.CFrame.LookVector * RaycastLength, params)
	wall = raycastResult and raycastResult.Instance or nil
	
	if wall and (hum.FloorMaterial == Enum.Material.Air or UserInputService:IsKeyDown(Enum.KeyCode.W)) then 
		hum.AutoRotate = false
		local goLeftOrRight = UserInputService:IsKeyDown(Enum.KeyCode.A) or UserInputService:IsKeyDown(Enum.KeyCode.D)
		-- climb up (and up with left or right)
		local isStopped = false
		if UserInputService:IsKeyDown(Enum.KeyCode.W) then
			climbAnim:AdjustSpeed(1)
			if goLeftOrRight then
				hrp.Velocity = Vector3.new(hrp.Velocity.X, GRAVITY_SPEED+8, hrp.Velocity.Z)
			else
				-- *0.6 is to fix jitter
				hrp.Velocity = Vector3.new(-hrp.Velocity.X*0.6, GRAVITY_SPEED+8, -hrp.Velocity.Z*0.6)
			end
		-- climb down (and down with left or right)
		elseif UserInputService:IsKeyDown(Enum.KeyCode.S) then
			climbAnim:AdjustSpeed(1)
			if goLeftOrRight then
				hrp.Velocity = Vector3.new(hrp.Velocity.X, GRAVITY_SPEED-8, hrp.Velocity.Z)+(hrp.CFrame.LookVector*4)
			else
				-- *0.6 is to fix jitter
				hrp.Velocity = Vector3.new(-hrp.Velocity.X*0.6, GRAVITY_SPEED-8, -hrp.Velocity.Z*0.6)+hrp.CFrame.LookVector
			end
		-- climb left and right
		elseif goLeftOrRight then
			climbAnim:AdjustSpeed(1)
			hrp.Velocity = Vector3.new(hrp.Velocity.X, GRAVITY_SPEED, hrp.Velocity.Z)
		-- motionless climb
		else
			climbAnim:AdjustSpeed(0)
			hrp.Velocity = Vector3.new(0, 0, 0)
			if stopPos == nil then
				stopPos = hrp.Position
			end
			chr:MoveTo(stopPos)
			isStopped = true
		end
		
		if not isStopped then
			stopPos = nil
		end
		
		if hum.FloorMaterial ~= Enum.Material.Air and UserInputService:IsKeyDown(Enum.KeyCode.W) then
			hrp.Velocity = Vector3.new(hrp.Velocity.X, hrp.Velocity.Y+8, hrp.Velocity.Z)
		end
		
		if not climbAnim.IsPlaying then
			climbAnim:Play()
		end
	else
		hum.AutoRotate = true
		-- cancel climb state for invalid climb attempts
		if chr.Humanoid:GetState() == Enum.HumanoidStateType.Climbing then
			chr.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing,false)
		end
		climbAnim:Stop()
	end
end)

Edit: Changed an immidiate number to GRAVITY_SPEED. Oops.
Edit2: Changed the value to fix jitter from 0.95 to 0.6. Now you can jump against the wall with no jitter.
Edit3: Updated motionless climb to actually be motionless.