I was working on a game of mine and ran across a problem. I am currently making a zone with heavy use of ladders in a “scaffolding” type theme, but I noticed that it would be extremely difficult for players to descend the ladders I have placed. Does anyone have any ideas for how to solve this problem?
I can’t think of any building-based solutions for this.
I wrote you some code to solve this. Basically it smoothly makes the player face the ladder when they’re falling.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local localPlayer = Players.LocalPlayer
local ladder = script.Parent
-- Add an ObjectValue with the value set to the trigger part
-- to the script or use the ladder as a default
local triggerPart = script.Parent
local duration = 3
local activationDistanceMax = 10
local activationDistanceMin = 0.5
local rotationSpeedMax = 0.8 -- value between 0 and 1
local rotationAcceleration = 1
local rotationSpeed = 0
local startTime = 0
local connection = nil
local function startConnection()
startTime = tick()
if connection then return end
connection = RunService.RenderStepped:Connect(function(step)
if tick() > startTime + duration then
connection:Disconnect()
connection = nil
local humanoid = localPlayer.Character and localPlayer.Character:FindFirstChild("Humanoid")
if humanoid then
humanoid.AutoRotate = true
end
return
end
local character = localPlayer.Character
if not character then return end
local humanoid = character:FindFirstChild("Humanoid")
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if (not humanoid) or (not humanoidRootPart) then return end
local hrpPosition = humanoidRootPart.Position
local horizontalDistance = (Vector2.new(hrpPosition.X, hrpPosition.Z) - Vector2.new(ladder.Position.X, ladder.Position.Z)).Magnitude
local humanoidState = humanoid:GetState()
local correctState = (humanoidState == Enum.HumanoidStateType.Freefall) or (humanoidState == Enum.HumanoidStateType.Jumping)
if horizontalDistance < activationDistanceMax and horizontalDistance > activationDistanceMin and correctState then
humanoid.AutoRotate = false
rotationSpeed += rotationAcceleration * step
if rotationSpeed > rotationSpeedMax then
rotationSpeed = rotationSpeedMax
end
local relativeLadderPosition = ladder.Position + Vector3.new(0, hrpPosition.Y - ladder.Position.Y, 0)
local goalCFrame = CFrame.lookAt(hrpPosition, relativeLadderPosition)
humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(goalCFrame, rotationSpeed)
else
humanoid.AutoRotate = true
rotationSpeed = 0
end
end)
end
-- When the trigger part is hit, make it so the player faces
-- towards the ladder so it's easy to climb
local function onTouched(part)
local character = part.Parent
if not character then return end
local player = Players:GetPlayerFromCharacter(character)
if not player or not (player == localPlayer) then return end
startConnection()
end
local touchedConnection
local function createConnection()
if touchedConnection then
touchedConnection:Disconnect()
end
touchedConnection = triggerPart.Touched:Connect(onTouched)
end
createConnection()
-- Steaming enabled can be such a pain
script.ChildAdded:Connect(function(child)
if child.Name == "Trigger" then
triggerPart = child.Value
if not triggerPart then
while not triggerPart do
triggerPart = child.Value
task.wait(0.1)
end
end
createConnection()
end
end)
(Goes inside the ladder in a Script set to Client RunContext)
I made a place file since setting up the script run context can be a little advanced, and it makes it easier to test it out.
I would recommend trigger parts (the orange part in the gifs above for the second ladder). The trigger parts make it so if the player passes through the area of the part, if they fall in the next few seconds close to the ladder they face towards it. The default is using the ladder as the trigger part, but that doesn’t work well if the player jumps over the ladder.
To make a trigger part, add an ObjectValue named “Trigger” to the script and set the ObjectValue’s Value to the trigger part. The trigger part should be invisible and non-collide.
From what I’ve seen in games, they usually have the ladder go on the inside of the scaffolding and a hole in the scaffolding floor for the player to go through. That way the player can walk into the ladder the proper direction. You could also use the code above if you don’t want to have to do that.