How to only allow the player to only climb certain models/parts

I made a script inside StarterCharacterScripts that disables the player climbing ability unless it touches a certain MeshPart which in this case is all the Ladders that are on the map inside a Folder. I’ve tried a few different ways of making this work but non seem to do job. The way I need it too. Any help would greatly appreciated.

robloxapp-20250216-1311003.wmv (1.1 MB)

Script:

local plr = game:GetService("Players").LocalPlayer

local hum = plr.Character:WaitForChild("Humanoid") -- You probably already have something available for this

local ladder = game.Workspace.Construction_Site.Ladders:GetChildren() -- The part you want to detect touches on

hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- disables Climbing

for index, value in ladder do
	
	value.Touched:Connect(function(meshPart) -- When they touch this part, enable their ability to climb

		if game.Players:GetPlayerFromCharacter(meshPart.Parent) then -- If it detects a humanoid then

			hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, true) -- Makes them able to climb

			task.wait(3) -- Give them time to climb up the ladder

		else
		
			hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- Makes them unable to climb
			
		end
	end)
end

--[[ladder.Touched:Connect(function(meshPart) -- When they touch this part, enable their ability to climb
	if game.Players:GetPlayerFromCharacter(meshPart.Parent) then 
		
		hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, true) -- Allows them to climb
		
		task.wait(3) -- Give them time to climb up the ladder
		
		hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- Makes them unable to climb
	end	
end)

ladder.TouchEnded:Connect(function(meshPart)

	if game.Players:GetPlayerFromCharacter(meshPart.Parent) then
	
		hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- Makes them unable to climb
		
	end
end)]]

would changing CanCollide on the ladders give the same result:

local plr = game:GetService("Players").LocalPlayer
local hum = plr.Character:WaitForChild("Humanoid") -- Get the player's humanoid
local ladders = game.Workspace.Construction_Site.Ladders:GetChildren() -- Get all ladder parts

-- Disable CanCollide by default so the player can't climb initially
for _, ladder in ipairs(ladders) do
	ladder.CanCollide = false

	ladder.Touched:Connect(function(meshPart)
		local character = meshPart.Parent
		local player = game.Players:GetPlayerFromCharacter(character)

		if player then -- If a player touches the ladder
			ladder.CanCollide = true -- Allow climbing

			task.wait(3) -- Give time to climb

			ladder.CanCollide = false -- Disable collision again
		end
	end)
end

No, the player just walks right through the ladder. it’s almost as if the script doesn’t even reach the for loop. I placed “Print Commands”, but they never come up in the output. If I run the script with the,

local plr = game:GetService("Players").LocalPlayer

local hum = plr.Character:WaitForChild("Humanoid") -- You probably already have something available for this

local ladder = game.Workspace.Construction_Site.Ladders:WaitForChild("Ladder")  -- The part you want to detect touches on

hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- disables Climbing

ladder.Touched:Connect(function(meshPart) -- When they touch this part, enable their ability to climb

	if game.Players:GetPlayerFromCharacter(meshPart.Parent) then

		hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, true) -- Allows them to climb
		task.wait(3) -- Give them time to climb up the ladder
	else
		hum:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- Makes them unable to climb
	end
end)

that works the best but then if I walk up to something beside the ladders the player with climb as if the climbing is true again. smh this is very confusing even with it being a simple script lol

robloxapp-20250217-1709006.wmv (7.8 MB)

Before I even touch any Ladders, I can’t climb as you can see when I try climbing the railing. But then as soon as I climb the ladder it allows me to (cuz I can only climb one, for whatever reason) it then seems like climbing in set to true again because I can climb over the railing afterwards.

I thought of another way. I used this for some switches I made for a 2 player obby to tell when the player was on the switch.

local Players = game:GetService("Players")
local ladderFolder = game.Workspace:WaitForChild("Construction_Site"):WaitForChild("Ladders")
local plr = game:GetService("Players").LocalPlayer
local newchar = plr.Character or plr.CharacterAdded:Wait()

newchar:FindFirstChild("Humanoid"):SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- disable climbing when there is a new character

local function safeCall(func)
	local success, err = pcall(func)
	if not success then
		warn("Error: " .. err)
	end
end

local function enableClimbing(humanoid)
	if humanoid then
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, true)
	end
end

local function disableClimbing(humanoid)
	if humanoid then
		task.wait(3) -- Grace period before disabling climbing
		humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
	end
end

local function onLadderTouched(hit)
	local character = hit.Parent
	local player = Players:GetPlayerFromCharacter(character)
	if player then
		print("Player touched ladder:", player.Name)
		safeCall(function()
			local humanoid = character:FindFirstChild("Humanoid")
			enableClimbing(humanoid)
		end)
	end
end

local function onOffPartTouched(hit)
	local character = hit.Parent
	local player = Players:GetPlayerFromCharacter(character)
	if player then
		print("Player left ladder:", player.Name)
		safeCall(function()
			local humanoid = character:FindFirstChild("Humanoid")
			disableClimbing(humanoid)
		end)
	end
end

local function createOffPart(ladder)
	local offPart = Instance.new("Part")
	offPart.Size = ladder.Size + Vector3.new(6, 6, 6) -- Slightly larger than the ladder ADJUST ME!!!
	offPart.Anchored = true
	offPart.CanCollide = false
	offPart.Transparency = 1
	offPart.Position = ladder.Position
	offPart.Name = "OffTouchPart"
	offPart.Parent = ladder

	offPart.Touched:Connect(onOffPartTouched)
end

local function processLadder(ladder)
	ladder.Touched:Connect(onLadderTouched)
	createOffPart(ladder)
end

-- Apply to existing ladders
for _, ladder in ipairs(ladderFolder:GetChildren()) do
	processLadder(ladder)
end

-- Handle dynamically added ladders (in case of streamingEnabled)
ladderFolder.ChildAdded:Connect(function(child)
	task.wait(0.1)
	processLadder(child)
end)


That worked like a charm THANK YOU so much!!!

you could also think outside the box and just put an invisible part on the ladder.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.