BoolValue.Changed or baseValue Instances don't work

Hello,
So basically I have this simple script where I have a NumberValue timer that depends on BoolValue.Changed.

local event -- BoolValue
local eventTimer -- NumberValue

event.Changed:Connect(function(val)
	if val == true then
		while val do
			eventTimer.Value -= 1
			wait(1)
		end
	end
end)

This is a piece taken from the whole script.

I’ve read other topics and tried their solution, with most of them being switching to :GetPropertyChangedSignal(), and no, that doesn’t solve it.

So confused with this, sometimes it does work, but after a slight or not-affecting (I believe) change in the script, it stops working, or, most of the time it just does not work. This does happen to the other baseValues, too. Is this an unfixed bug?

Thank you for reading :slightly_smiling_face:

In this case, the bool and numeric are inside the script. (Not that it matter where they are)

local event = script.event 
local eventTimer  = script.eventTimer 

eventTimer.Value = 10
event.Changed:Connect(function(val)
	while val do
		if event.Value then
			eventTimer.Value -=1 print(eventTimer.Value)
			task.wait(1)
		end	
	end
end)

task.wait(5)
event.Value = true

However, if you switch the event.Value to false after being true.
You’ll probably lock up. There is no break in the loop or used wait in that case.
This will lock up, timeout or keep counting downwards depending on state after being true

Slight change …

local event = script.event 
local eventTimer  = script.eventTimer 

eventTimer.Value = 10
event.Changed:Connect(function()
	
		while event.Value do
			eventTimer.Value -=1 print(eventTimer.Value)
			task.wait(1)
		end	

end)

task.wait(5)
event.Value = true

task.wait(5)
event.Value = false

Other ways to do this, don’t like the constant read. But, this whole thing as no purpose.
Everything will happen in the event.Changed triggering nothing else.

1 Like

Good explanation…
It seems to work now, however the while do loop doesn’t seem to end?

I don’t know how to really use task functions… might learn more about it.

Okay… simply just by adding another debounce.

local timerActive = false -- this;

event.Changed:Connect(function(val)
	if val then
		timerActive = true
		while event.Value do
			eventTimer.Value -=1 print(eventTimer.Value)
			task.wait(1)
		end	
	else
		timerActive = false
		eventTimer.Value = 0
	end
end)

Anyway, thank you for the feedbacks :smile:

Changed doesn’t only apply to Value, instead it applies to every property such as Name.

Instead, either you check if val is “Value” (because val is the name of the property changed) or you use GetPropertyChangedSignal("Value"). They both work and show the same results.

event.Changed:Connect(function(val)
     if val == "Value" then
          -- do something
     end
end
-- OR
event:GetPropertyChangedSignal("Value"):Connect(function()
     -- do something
end)

you probably did it wrong

also you don’t need to use Changed or GetPropertyChangedSignal as the loop already checks if event.Value is true.

while true do
	if event.Value == true then
		eventTimer.Value -= 1
		if eventTime.Value <= 0 then
			event.Value = false
			eventTimer.Value = 0
		end
	else
		eventTimer.Value = 0
	end
	
	task.wait(1)
end

You guys can do repeat until the timer reaches 0

I tried that before, and it did not work. Perhaps I was doing it wrong.

image

Here in the Create Documentation, it clearly says only .Value.

i never knew that before. im used to this

also, i didn’t only talked about Value in my answer, i also talked about not using Changed anymore

Ya, that is a janky test … it ends lower in the script with the line “event.Value = false”
This ends the loop as the tested value is no longer true. Myself I like to pull the value to a variable then work with that and not constantly read/writing like that. It was more of a show for the test.
Was able to get away with that as the while loop is in it’s own Connect(function().

local event = script.event 
local eventTimer  = script.eventTimer 

eventTimer.Value = 10 -- this should be set up manualy and not like this

event.Changed:Connect(function()
	
	if event.value == true then
		local count = eventTimer.Value
		while true do count -=1
			if count < 1 then break end
			task.wait(1)
		end	
		
		-- here

	end
	
end)

event.Value = true -- this should be triggered from some other script

--[[
Not sure how you're using this .. Took it as a stand-alone timer.
When the loop is done, where I marked "here" you would fire a remote
or test for the event.Value to be changed back to false on the triggering script.

If you're using this as a stall in a script, it may be better off using a 
task.wait(eventTimer.Value)

There is no real explanation of how this is being used.
--]]

Little side-note, you can always specify what property to listen to rather than globally. Why not?

local int = Instance.new("IntValue")

int:GetPropertyChangedSignal("Value"):Connect(function()
    print("changed")
end)

Just use: FastValue a replacement for Value Instances that is better than Remotes and Bindables