Imagine it like this: You have a function that has a lot of things happening and you don’t want to go through every line and put if not variable then return end… What would you do then? I would repeat until it changes to false but it wouldn’t continue the current thread. Please help!
I have a vague idea of what you’re trying to say, but could you explain it a bit more clearly? I can’t do anything with what you said here. Maybe provide some example code as well.
What I am trying to do is to end an function, when a variable changes to a specific value.
script.Parent.Generator.Lever.Lever.Attachment.ProximityPrompt.Triggered:Connect(function()
script.Parent.Generator.Lever.Lever["Lever sound"]:Play()
script.Parent.Generator.Lever.Lever.Start:Play()
_G.TweenInstance(script.Parent.Generator.Lever.Lever.Engine,TweenInfo.new(10),{PlaybackSpeed = 1})
_G.TweenInstance(script.Parent.Generator.Lever.Lever,TweenInfo.new(1.2),{Position = script.Parent.Generator.Lever.LeverToGoOpen.Position})
pulled = true
wait(10)
if pulled then
pulled = false
script.Parent.Generator.Lever.Lever.Attachment.ProximityPrompt.Enabled = false
script.Parent.Generator.Lever.Lever["Lever sound"]:Play()
_G.TweenInstance(script.Parent.Generator.Lever.Lever,TweenInfo.new(1.2),{Position = script.Parent.Generator.Lever.LeverToGoBack.Position})
end
end)
See that “if pulled then” statement? Could that somehow be replaced? It would be best if it repeatedly checked a value and then returned the function if changed.
What are you trying to achieve exactly? From this code, it appears that you want the lever to open when the proximity prompt is triggered, then automatically close after some amount of time. If that’s what you want, then this code looks fine. If not, then clearly explain the behavior you are trying to achieve and I can help you from there.
Also side note, you should use variables to store your objects, it makes your code much more readable and efficient.
For example, at the top of your code you can do
local Lever = script.Parent.Generator.Lever
and use this ‘Lever’ variable instead of having to use ‘script.Parent.Generator.Lever’ every single time you want to use it.
It is harder to explain than I thought it would be. I’ll try my best! Imagine you have a proximity prompt that shines 3 lights after some time when held. That would be easy to make, yes, but how do I return the whole function after the trigger ended?
Are you saying you want the function to stop/return only after the ProximityPrompt.TriggerEnded
event fires, or if it fired after the ProximityPrompt.Triggered
event did?
If so, the solution is simple. Let me first say this, though: when the prompt is triggered, if it will perform an action that is visible to all players, you should add a debounce so that the event threads do not interfere with each other.
What you can do is create a variable that will hold a boolean
. Everytime the TriggerEnded
event is triggered, check if the variable – I’ll call this variable triggerEnded
– is true
or not. If triggerEnded
is false
(not true
), change it to true
. Then inside the function connected to the Triggered
event, check if triggerEnded
is true
, and if not, wait until it is true
. Here’s an example:
local prompt = -- [The `ProximityPrompt`'s location.]
local debounce = false
local triggerEnded = false
prompt.TriggerEnded:Connect(function()
if not triggerEnded then triggerEnded = true end
end)
prompt.Triggered:Connect(function()
if debounce then return end
debounce = true
-- Add code here.
if not triggerEnded then
repeat
task.wait()
until triggerEnded
end
triggerEnded = false
debounce = false
end)
Now, I am assuming that this ProximityPrompt
is server-sided and that the action triggered will be visible to all clients, which is why I added a debounce to prevent thread collisions. If the prompt is client-sided, you can use the snippet I provided as an example. However, if the prompt is server-sided and the debounce is unnecessary, you’ll need to use a dictionary instead of the single triggerEnded
variable:
local triggersEnded = {}
prompt.TriggerEnded:Connect(function(player)
if triggersEnded[player] then return end
triggersEnded[player] = true
end)
prompt.Triggered:Connect(function(player)
-- Check if a thread is already running for this player.
-- The `TriggerEnded` event couldn't have been triggered without the `Triggered` event being triggered.
if triggersEnded[player] then return end
-- Add code here.
if not triggersEnded[player] then
repeat
task.wait()
until triggersEnded[player]
end
triggersEnded[player] = nil -- You can also set this to `false`.
end)
Ok good, but I want to end the script during the code above the repeat, not after…
Why not use PromptEnded:Wait() instead a loop?
Because if someone else lets go of the prompt’s trigger, it’ll trigger for the current player and all the other players.
Oh that’s true
Chars here god…
Oh, are you saying that if the player lets go of the trigger while the code is running, you want the code to stop?
Yes! that is exactly what I am looking for.
You can use threads
. When using a thread
, you can task.cancel()
/coroutine.close()
it at any time.
However, threads
don’t yield code outside of themselves. So, in the following example, “B” would be printed first:
task.delay(5, print, "A") -- Yields 5 seconds for "A" to be outputted.
print("B")
This means that your function connected to ProximityPrompt.Triggered
will return, however the code (thread
) inside of it would still be running until it stops or gets cancelled in some way.
If you don’t mind the function returning and the code inside the thread
still running, here’s an example for your script:
local threads = {}
prompt.TriggerEnded:Connect(function(player)
task.cancel(threads[player])
end)
prompt.Triggered:Connect(function(player)
threads[player] = task.spawn(function()
-- Code here.
end)
-- The thread above won't yield the code down here,
-- so the function will return while the thread runs.
end)
If you do mind the function returning, you can use a repeat until
statement along with the thread
.
local threads = {}
prompt.TriggerEnded:Connect(function(player)
if not threads[player] then return end
task.cancel(threads[player])
threads[player] = nil
end)
prompt.Triggered:Connect(function(player)
threads[player] = task.spawn(function()
-- Code here.
-- In case the thread finishes before the player lets go of the trigger.
threads[player] = nil
end)
repeat -- Wait for the thread to stop running.
task.wait()
until not threads[player]
end)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.