I am currently attempting to develop a system where a train will start and stop when using ‘resume’ and ‘pause’. The resume aspect of my script currently works. although the pause doesnt. Just asking for some feedback on whats going wrong. thanks!
local TweenService = game:GetService("TweenService")
local SecondsPerStud = 0.05
game.Players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
if message:lower() == "pause" then
script.Parent.can.Value = false
end
if message:lower() == "resume" then
script.Parent.can.Value = true
end
end)
end)
while true do
wait()
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
local tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
if script.Parent.can.Value == false then
tween:Pause()
else
tween:Play()
tween.Completed:Wait()
end
end
end
Pausing won’t work because your tween is only local on the loop of each track.
I believe for you to solve this issue and for the function bettter is to use the Changed event rather than running a continous index loop to pause an already known tween.
local tween = nil
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause() end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
end
end
local TweenService = game:GetService("TweenService")
local SecondsPerStud = 0.05
game.Players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
if message:lower() == "pause" then
script.Parent.can.Value = false
end
if message:lower() == "resume" then
script.Parent.can.Value = true
end
end)
end)
script.Parent.can.Changed:Connect(function()
local tween = nil
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause() end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
end
end
end)
Hm, you might want to run some prints around to make sure “can” is false and is a bool, the position of v or “script.Parent” isn’t something crazy, pausing is being runned, and making sure that it goes past “tween.Completed:Wait()”
script.Parent.can.Changed:Connect(function()
local tween = nil
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause(); print("Paused.") end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
print("Resumed.")
end
end
end)
Neither print, although it does resume, so I am guessing that tween.Completed:Wait() might be stopping the print from running.
Although I do not know whats going on with the pause.
Just noticed I am setting nil everytime the value is changed, fixing and testing now.
Alright, I got the pause and resume working but not functioning as I intend.
When I pause it stops as I want it to, but then when I resume it goes back to the start of the track.
Do you know why?
local TweenService = game:GetService("TweenService")
local SecondsPerStud = 0.05
game.Players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
if message:lower() == "pause" then
script.Parent.can.Value = false
end
if message:lower() == "resume" then
script.Parent.can.Value = true
end
end)
end)
local tween = nil
script.Parent.can.Changed:Connect(function()
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause(); print("Paused.") end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
print("Resumed.")
end
end
end)
Yes, but then the same dilema will arise when setting the dictionary automatically from the track nodes. I will need to use getchildren to index the dictionary.
I’m not sure what you mean, I’m pretty sure you can do a simple dictionary check to make the track just not tween it again if it’s true. I have an example down below.
local tween = nil
local passedTracks = {}
script.Parent.can.Changed:Connect(function()
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new(
(v.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause(); print("Paused.") end
elseif not passedTracks[v] then
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
passedTracks[v] = true
if v == FINALTRACK then
passedTracks = {}
end
print("Resumed.")
end
end
end)
Define the Tween information outside of the changed function, so you’re not redefining it each time you change the ‘Can’ value.
Define a ‘CurrentPoint’ outside of this changed function, which acts as the current node within the track that your train is aiming to move towards. Increment to the next point after the previous is reached. When you pause and resume again, your tween’s goal should be this CurrentPoint.
local tween = nil
local current = nil
script.Parent.can.Changed:Connect(function()
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
current = v
local Info = TweenInfo.new(
(current.Position - script.Parent.Position).Magnitude * SecondsPerStud,
Enum.EasingStyle.Linear
)
if script.Parent.can.Value == false then
if tween then tween:Pause(); print("Paused.") end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = current.CFrame})
tween:Play()
tween.Completed:Wait()
current = v
print("Resumed.")
end
end
end)
Something like this?
Amending this: It still returns to the beginning of the track,
Not exactly what I had in mind, however I’ve made your code work quickly with the use of a BindableEvent. Do mind that when you pause it may not update immediately due to the fact that if a tween is already playing, it will have to wait until that tween has completed. And do note it isn’t the most effective way of doing such.
local tween = nil
local Can = true
local PauseEvent = Instance.new("BindableEvent")
script.Parent.can.Changed:Connect(function(State)
Can = State
if State then
PauseEvent:Fire()
end
end)
for _,v in pairs(workspace.Workspace.Transport.Track:GetChildren()) do
local Info = TweenInfo.new((v.Position - script.Parent.Position).Magnitude * SecondsPerStud,Enum.EasingStyle.Linear)
if script.Parent.can.Value == false then
if tween then
tween:Pause();
print("Paused.")
PauseEvent.Event:Wait()
end
else
tween = TweenService:Create(script.Parent, Info, {CFrame = v.CFrame})
tween:Play()
tween.Completed:Wait()
print("Resumed.")
end
end
Is there any way of doing it where I can make it pause anywhere during the track, my goal in this is to make a start stop button on a gui inwhich the driver can click.
By the way, that script with the bindablefunction doesnt work.
Please try the code again as I’ve updated the loop to iterate through your original path for your Track, as I had changed it simply to workspace.Track:GetChildren() to experiment with it myself and forgot to change it back. It should definitely work.
However, I can’t say that I’ve ever done anything like this myself as I don’t believe I’ve seen a train system that can be driven by a player utilizing TweenService, as trains that use TweenService that I’ve seen typically are those with constant movement, such as in Jailbreak. I’m afraid I wouldn’t know too much about what you can do to achieve this, so I suggest researching trains that can be driven and seeing how they were done.
My suggestion if you still want to use this system with your GUI is to have a RemoteEvent that fires to the server, checks that the person who fired it is the driver, then pause the tween. Keep track of the current ‘node’ in the track that the train is moving towards and when the driver resumes again, create a new tween with the train’s current position and move it towards that node, before switching back to the other system where it moves from node to node. If this doesn’t work, unfortunately there isn’t much more help I can provide because this isn’t something I’ve done before.