Heyo Devforum! Recently, I have been scripting my own zipline from scratch, and I have successfully done it, but I have trouble with one problem. I want it so that my player can jump off of the zipline when he/she is on the zipline and jumps. I tried using humanoid.Jumping to see whether the player has jumped on the zipline, but it never works, and it only detects it once the player is off the zipline and jumping on the ground. Here is my script:
repeat wait() until game.Workspace:WaitForChild("Tower of Troubling Tutorials")
local ziplines = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines:GetChildren()
local tweenservice = game:GetService("TweenService")
for i, zipline in pairs(ziplines) do
local isonzip = false
local line = zipline.Line
local finish = zipline.End
local start = zipline.Start
local slider = script.Slider
local animation = script.ZiplineHold
start.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
if not isonzip then
isonzip = true
local character = hit.Parent
local humanoid = hit.Parent.Humanoid
local sliderclone = slider:Clone()
sliderclone.Parent = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines
sliderclone.PrimaryPart.Position = start.Position
local sliderpart = sliderclone.SliderPart
local movingsliderpart = sliderclone.Part
local weld = Instance.new("Weld")
weld.Part0 = character.Head
weld.Part1 = sliderpart
weld.Parent = sliderpart
sliderpart.CFrame = character.Head.CFrame
local tweeninfo = TweenInfo.new(2)
local goal = {}
goal.CFrame = finish.CFrame
local tween = tweenservice:Create(movingsliderpart, tweeninfo, goal)
tween:Play()
local loadanimation = humanoid:LoadAnimation(animation)
loadanimation:Play()
humanoid.Jumping:Connect(function()
print("YEs")
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end)
wait(2)
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end
end
end)
end
If you have any trouble understanding anything of my code, I will be happy to explain. Thank you!
Instead of asking the Humanoid whether the player jumped, we can go straight to the source of how players move. If you run your game, you’ll see PlayerModule under StarterPlayerScripts.
The PlayerModule is the code responsible for making your character and camera move. We can ask it instead whether the player is trying to jump. You might try something like this.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Player = Players.LocalPlayer
local PlayerModule = require(Player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local Controls = PlayerModule:GetControls()
-- somewhere later in your zipline function
while not Controls:GetActiveController():GetIsJumping() do
RunService.Heartbeat:Wait()
print("waiting for jump")
end
print("player jumped")
The downside to this is that the control module doesn’t fire an event when the player jumps like Humanoid does, so you’re stuck busy waiting in a while loop.
repeat wait() until game.Workspace:WaitForChild("Tower of Troubling Tutorials")
local ziplines = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines:GetChildren()
local tweenservice = game:GetService("TweenService")
local runservice = game:GetService("RunService")
local player = game.Players.LocalPlayer
local playermodule = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local controls = playermodule:GetControls()
for i, zipline in pairs(ziplines) do
local isonzip = false
local line = zipline.Line
local finish = zipline.End
local start = zipline.Start
local slider = script.Slider
local animation = script.ZiplineHold
start.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
if not isonzip then
isonzip = true
local character = hit.Parent
local humanoid = hit.Parent.Humanoid
local sliderclone = slider:Clone()
sliderclone.Parent = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines
sliderclone.PrimaryPart.Position = start.Position
local sliderpart = sliderclone.SliderPart
local movingsliderpart = sliderclone.Part
local weld = Instance.new("Weld")
weld.Part0 = character.Head
weld.Part1 = sliderpart
weld.Parent = sliderpart
sliderpart.CFrame = character.Head.CFrame
local tweeninfo = TweenInfo.new(2)
local goal = {}
goal.CFrame = finish.CFrame
local tween = tweenservice:Create(movingsliderpart, tweeninfo, goal)
tween:Play()
local loadanimation = humanoid:LoadAnimation(animation)
loadanimation:Play()
while not controls:GetActivateController():GetIsJumping() do
runservice.HeartBeat:Wait()
print("Wait")
end
print("Jumped")
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
wait(2)
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end
end
end)
end
Hello AstroCode! After fixing everything, it works now so I must thank you on that, but now when the player DOESN’T jump, the weld and tween never destroy and stop. Did I place in the code block wrong?
Script:
repeat wait() until game.Workspace:WaitForChild("Tower of Troubling Tutorials")
local ziplines = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines:GetChildren()
local tweenservice = game:GetService("TweenService")
local runservice = game:GetService("RunService")
local player = game.Players.LocalPlayer
local playermodule = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local controls = playermodule:GetControls()
for i, zipline in pairs(ziplines) do
local isonzip = false
local line = zipline.Line
local finish = zipline.End
local start = zipline.Start
local slider = script.Slider
local animation = script.ZiplineHold
start.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
if not isonzip then
isonzip = true
local character = hit.Parent
local humanoid = hit.Parent.Humanoid
local sliderclone = slider:Clone()
sliderclone.Parent = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines
sliderclone.PrimaryPart.Position = start.Position
local sliderpart = sliderclone.SliderPart
local movingsliderpart = sliderclone.Part
local weld = Instance.new("Weld")
weld.Part0 = character.Head
weld.Part1 = sliderpart
weld.Parent = sliderpart
sliderpart.CFrame = character.Head.CFrame
local tweeninfo = TweenInfo.new(2)
local goal = {}
goal.CFrame = finish.CFrame
local tween = tweenservice:Create(movingsliderpart, tweeninfo, goal)
tween:Play()
local loadanimation = humanoid:LoadAnimation(animation)
loadanimation:Play()
while not controls:GetActiveController():GetIsJumping() do
runservice.Heartbeat:Wait()
print("Wait")
end
print("Jumped")
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
wait(2)
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end
end
end)
end
Oh right, that’s because it’s stuck in an endless loop waiting for the player to jump. I didn’t account for the zipline ending. What we can do is wrap the while loop in a coroutine. What this does is it runs the loop on another thread, so both the while loop and the rest of the function can run at the same time.
coroutine.wrap(function()
while not controls:GetActiveController():GetIsJumping() do
runservice.Heartbeat:Wait()
end
end)()
But now if the zipline stops before you jump, the coroutine will still continue to wait until you jump. We don’t want that. Instead, we need to tell it to stop if isonzip = false.
coroutine.wrap(function()
while isonzip and not controls:GetActiveController():GetIsJumping() do
runservice.Heartbeat:Wait()
end
end)()
Heyo AstroCode! I have ran into one last peculiar problem. Whenever a player jumps into the start, the player will just teleport to the same spot which is the lobby. I am not sure why this is happening. Is there something wrong with my script?
Script:
repeat wait() until game.Workspace:WaitForChild("Tower of Troubling Tutorials")
local ziplines = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines:GetChildren()
local tweenservice = game:GetService("TweenService")
local runservice = game:GetService("RunService")
local player = game.Players.LocalPlayer
local playermodule = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local controls = playermodule:GetControls()
for i, zipline in pairs(ziplines) do
local isonzip = false
local line = zipline.Line
local finish = zipline.End
local start = zipline.Start
local speed = zipline.Speed
local slider = script.Slider
local animation = script.ZiplineHold
start.Touched:Connect(function(hit)
if not isonzip and player.Character and hit:IsDescendantOf(player.Character) then
isonzip = true
local character = player.Character
local humanoid = character.Humanoid
local sliderclone = slider:Clone()
sliderclone.Parent = game.Workspace:WaitForChild("Tower of Troubling Tutorials").Ziplines
sliderclone.PrimaryPart.CFrame = start.CFrame
local sliderpart = sliderclone.SliderPart
local movingsliderpart = sliderclone.Part
local weld = Instance.new("Weld")
weld.Part0 = character.Head
weld.Part1 = sliderpart
weld.C1 = CFrame.new(0,-0.9,0)
weld.Parent = sliderpart
sliderpart.CFrame = character.Head.CFrame
local tweeninfo = TweenInfo.new(speed.Value)
local goal = {}
goal.CFrame = finish.CFrame
local tween = tweenservice:Create(movingsliderpart, tweeninfo, goal)
tween:Play()
local loadanimation = humanoid:LoadAnimation(animation)
loadanimation:Play()
coroutine.wrap(function()
while isonzip and not controls:GetActiveController():GetIsJumping() do
runservice.Heartbeat:Wait()
end
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end)()
wait(speed.Value)
weld:Destroy()
loadanimation:Stop()
sliderclone:Destroy()
isonzip = false
end
end)
end