You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I’m trying to disconnect a function as soon as a value reaches 0. The value counting down works and everything pretty much does except for disconnecting.
What is the issue? Include screenshots / videos if possible!
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined the game!")
wait(8)
local EMERGENCYSTOP = false
warn("HELPP")
local connection
--local player = script.Parent.Parent
local IsWantedBoolean = player:WaitForChild("IsWantedBoolean",10)
print(player:FindFirstChild("IsWantedBoolean"))
print(IsWantedBoolean)
print(IsWantedBoolean.Value)
local function Counter()
IsWantedBoolean:SetAttribute("Counting", true)
while true do
if EMERGENCYSTOP == true then
break
elseif IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
if connection == nil then
print("Errro")
end
connection:Disconnect()
IsWantedBoolean:SetAttribute("Counting", false)
break
end
wait(1)
print(IsWantedBoolean:GetAttribute("WantedTimeRemaining"))
IsWantedBoolean:SetAttribute("WantedTimeRemaining", IsWantedBoolean:GetAttribute("WantedTimeRemaining") -1)
print(IsWantedBoolean:GetAttribute("WantedTimeRemaining"))
end
end
--wait(3)
local function runtime()
warn("Ancestory Changed")
if IsWantedBoolean then
warn("Good")
-- Check if wanted level has a number
if IsWantedBoolean:GetAttribute("WantedTimeRemaining") ~= 0 then
-- check the amount and then start counting I guess
print("Counter call")
connection = Counter()
else
warn("We're Zero!")
end
else
error("TheBoolIsNil")
end
end
local function attributeChanged(attributeName)
print(attributeName, "Changed")
if attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 and IsWantedBoolean:GetAttribute("Counting") ~= true then
print("Bruh")
connection = Counter()
elseif attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
connection:Disconnect()
end
end
IsWantedBoolean.AttributeChanged:Connect(attributeChanged)
wait(2)
runtime()
end)
Players.PlayerRemoving:Connect(function(player)
print(player.Name .. " left the game!")
end)
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ve tried re-writing this over and other and checking for issues. Additionally I tried setting it up exactly like this roblox api article but still no luck sadly. If anyone knows if i’m connecting this wrong, please let me know asap. Thanks!
variable connection is nil, it’s not set to store anything, i know you have an connection = Counter() in the runtime function, but the problem is, everytime a player is added it resets the variable:
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined the game!")
wait(8)
local EMERGENCYSTOP = false
warn("HELPP")
local connection -- this resets it
and i dont see a line where it calls runtime() before checking if connection is nil
Well, one reason the connection variable is inside of the player added function is so that it’ll remain individual to the player and not effect others when they join (please correct me if that’s not how it works, Also I put the connection outside of the player added and it’s the same scenario).
Also, the only reason there is not a check for connection is because it isn’t set until runtime is called
it will not work unless Counter() returns a value which i dont see it doing.
and for note, you can only disconnect objects returned by :connect(), if ur trying to disconnect something else
Firstly, Counter returns void so doing connection = Counter() doesn’t do anything.
Secondly, you can’t disconnect from a function so doing connection = Counter and then connection:Disconnect() would be invalid. If you’re trying to stop the while true do loop, use the break keyword or use coroutines instead.
Thirdly, use task.wait instead of wait.
Edit: here’s a valid example of dealing with connections:
local connection = nil
connection = game:GetService("Players").PlayerAdded:Connect(function(plr)
if plr.Name == "SomeImportantPerson" then
print("VIP has finally joined!")
connection:Disconnect()
else
print("Not yet...")
end
end)
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
task.wait(8)
local EMERGENCYSTOP = false
local connection = true
local IsWantedBoolean = player:WaitForChild("IsWantedBoolean", 10)
local function Counter()
if not connection then
return
end
IsWantedBoolean:SetAttribute("Counting", true)
while true do
if EMERGENCYSTOP then
break
elseif IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
connection = false
IsWantedBoolean:SetAttribute("Counting", false)
break
end
task.wait(1)
IsWantedBoolean:SetAttribute("WantedTimeRemaining", IsWantedBoolean:GetAttribute("WantedTimeRemaining") -1)
end
end
local function runtime()
if IsWantedBoolean then
if IsWantedBoolean:GetAttribute("WantedTimeRemaining") ~= 0 then
connection = true
end
end
end
local function attributeChanged(attributeName)
if attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 and IsWantedBoolean:GetAttribute("Counting") ~= true then
connection = true
elseif attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
connection = false
end
end
IsWantedBoolean.AttributeChanged:Connect(attributeChanged)
task.wait(2)
runtime()
end)
Players.PlayerRemoving:Connect(function(player)
end)
This probably isn’t the behavior you’re looking for but this is how you’d create a variable which controls whether or not the body of a function should proceed with execution, in this case “connection” is acting as a debounce, you’ll need to change where I’ve toggled its assigned Boolean value if necessary.
You cannot connect a function, connection refers to the RBXScriptSignal object (that is what has the :Disconnect() function). To create a connection you must call :Connect() on an event.
You have to tell the code inside the function to stop. There isn’t a built in way to stop a function in it’s tracks (for complex reasons).
For example, you could do something like this:
local function counter()
local count = 0
local active = true
while active do
count += 1
print(count)
task.wait(1)
end
local function fakeDisconnectFunction()
active = false
end
return {Disconnect = fakeDisconnectFunction}
end
When you tell your code to repeat, it’s going to repeat. What you can do though is add an end condition.
In the code above, the repeating stops when the boolean “active” becomes false. You probably want to do this somewhere else in your code, so we send out a function that sets “active” to false that can be used elsewhere.
For example, you could use the code above like this:
local function counter()
local count = 0
local active = true
while active do
count += 1
print(count)
task.wait(1)
end
local function fakeDisconnectFunction()
active = false
end
return {Disconnect = fakeDisconnectFunction}
end
local fakeConnection = counter()
wait(2.5)
fakeConnection:Disconnect() -- Can use fakeConnection.Disconnect(), both work (the : sends the fakeDisconnectFunction the entire table too)
You can use the return keyword. The return keyword lets a function output a value.
For example:
local function getMessage()
return "Hello" -- when you run the function it evaluates to "Hello"
end
print(getMessage()) -- same as print("Hello") because "Hello" is outputted by our function getMessage
Output:
"Hello"
Similarly, instead of returning the string “Hello”, we can return a function from inside the other function:
local function getFunction()
local function myFunction()
print("Fizz")
end
return myFunction -- myFunction is the name of our function. If you want to run a function, add ()
end
local func = getFunction()
func()
Output:
"Fizz"
This might make it make more sense:
local function func()
end
is actually just:
local func = function() end
When you create a function with local function functionName() it’s actually just creating a variable and setting that variable’s value to a new function.
I think I understand the function thing you’re talking about but my script still has the Disconnect error
local fakeConnection
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined the game!")
wait(8)
local EMERGENCYSTOP = false
warn("HELPP")
--local player = script.Parent.Parent
local IsWantedBoolean = player:WaitForChild("IsWantedBoolean",10)
print(player:FindFirstChild("IsWantedBoolean"))
print(IsWantedBoolean)
print(IsWantedBoolean.Value)
local active = true
local function Counter()
IsWantedBoolean:SetAttribute("Counting", true)
while active do
if EMERGENCYSTOP == true then
break
end
--[[elseif IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
if connection == nil then
print("Errro")
end
connection:Disconnect()
IsWantedBoolean:SetAttribute("Counting", false)
break
end]]
wait(1)
print(IsWantedBoolean:GetAttribute("WantedTimeRemaining"))
IsWantedBoolean:SetAttribute("WantedTimeRemaining", IsWantedBoolean:GetAttribute("WantedTimeRemaining") -1)
print(IsWantedBoolean:GetAttribute("WantedTimeRemaining"))
end
local function fakeDisconnectFunction()
active = false
IsWantedBoolean:SetAttribute("Counting", false)
end
return {Disconnect = fakeDisconnectFunction}
end
--wait(3)
local function runtime()
warn("Ancestory Changed")
if IsWantedBoolean then
warn("Good")
-- Check if wanted level has a number
if IsWantedBoolean:GetAttribute("WantedTimeRemaining") ~= 0 then
-- check the amount and then start counting I guess
print("Counter call")
fakeConnection = Counter()
else
warn("We're Zero!")
end
else
error("TheBoolIsNil")
end
end
local function attributeChanged(attributeName)
print(attributeName, "Changed")
if attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 and IsWantedBoolean:GetAttribute("Counting") ~= true then
print("Bruh")
fakeConnection = Counter()
elseif attributeName == "WantedTimeRemaining" and IsWantedBoolean:GetAttribute("WantedTimeRemaining") <= 0 then
fakeConnection:Disconnect()
end
end
IsWantedBoolean.AttributeChanged:Connect(attributeChanged)
wait(2)
runtime()
--local fakeConnection = Counter()
end)
Players.PlayerRemoving:Connect(function(player)
print(player.Name .. " left the game!")
end)
The function acts kind of like a normal connection, so if you want to use it later in your code you’ll need to store it. I think the problem with your code is that you create the fake connection twice.
I’m not sure where the problem is . There are some good ways you can refactor your code though:
Instead of having a bunch of variables and stuff, why not just use the Attribute “WantedTimeRemaining” to manage everything? For example, if the Attribute is greater than 0 you can assume the player is wanted and if it isn’t then you can assume they aren’t. Then, when the attribute becomes greater than zero, you can start a while loop like so:
while IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 do
That makes your code:
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local countdownActive = false
local function attributeChanged(attributeName)
if attributeName == "WantedTimeRemaining" then
if (IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0) and (not countdownActive) then
countdownActive = true
while IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 do
IsWantedBoolean:SetAttribute("WantedTimeRemaining", IsWantedBoolean:GetAttribute("WantedTimeRemaining") -1)
wait(1)
end
countdownActive = false
end
end
end
IsWantedBoolean.AttributeChanged:Connect(attributeChanged)
--wait(2) -- I'd recommend removing this
--runTime()
-- Instead of using runTime, we can just use the attributeChanged handler to process the initial value.
attributeChanged("WantedTimeRemaining") -- process the initial WantedTimeRemaining value
end)
With explanatory comments
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local countdownActive = false
local function attributeChanged(attributeName)
-- if correct attribute
if attributeName == "WantedTimeRemaining" then
-- if the count-downer-thingy should start
if (IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0) and (not countdownActive) then
-- set the bool to let the rest of the code know the counter is going
countdownActive = true
-- run the counter until it should stop
while IsWantedBoolean:GetAttribute("WantedTimeRemaining") > 0 do
IsWantedBoolean:SetAttribute("WantedTimeRemaining", IsWantedBoolean:GetAttribute("WantedTimeRemaining") -1)
wait(1)
end
-- set the bool to let the rest of the code know the counter is not going
countdownActive = false
end
end
end
IsWantedBoolean.AttributeChanged:Connect(attributeChanged)
--wait(2) -- I'd recommend removing this
--runTime()
-- Instead of using runTime, we can just use the attributeChanged handler to process the initial value.
attributeChanged("WantedTimeRemaining") -- process the initial WantedTimeRemaining value
end)
Do you need to set the connection variable as “nil” first or can you just set the connection variable to the PlayerAdded event directly? I confused on why connection needs to be set as nil.