I am attempting to detect when a value across a module script has changed instead of relying on a while loop.
To clarify, there are two different module scripts. This code is inside of one of the module Scripts attempting to (after using require) detect a change in a boolean in the other module script.
The issue is that this module script is unable to detect any changes and nothing is printed. Does Value.Changed not work across module scripts? Any help would be appreciated.
.Changed is a property of Instance values, and can’t work for simple variable booleans. You could instead add a callback system, to manually create the same effect. I would structure the module something along the lines of this:
local StateMachine = {}
--// Variables
local isChasing = false -- if current state is chasing
local isChasingCallbacks = {} -- callbacks when state changes
--// Methods
function StateMachine.OnChasingChange(callbackFuc)
-- add a callback function to be called when state changes
table.insert(isChasingCallbacks, callbackFuc)
end
function StateMachine.SetChasing(newValue)
-- update chasing value
isChasing = newValue
-- fire all callbacks
for i, func in pairs(isChasingCallbacks) do
func(isChasing)
end
end
-- get current state
function StateMachine.IsChasing()
return isChasing
end
return StateMachine
you could use metatables for detecting value change
--Modules script
local module = {}
module.value = 2
local Changed = {
value = function(t,k,v)
print(k," changed to ",v)
end
}
local mt = {}
mt.__newindex = function(self,k,v)
rawset(self,k,v)
if Changed[k] then Changed[k](self,k,v) end
end
return setmetatable(module,mt)
--Script
local module = require(MyModule)
module.value = 3 -- prints "value changed to 3"
From what I understand, you want to detect when a value set inside a module changes. So, to do this without using a loop, you can type this:
The first module
local module = {}
module.value = Instance.new("NumberValue") -- Can be an IntValue, too.
-- Update the value.
task.wait(2)
module.value.Value = 3
task.wait(2)
module.value.Value = 10
return module
The second module
local OtherModule = require(--[[module location here]])
local module = {}
OtherModule.value:GetPropertyChangedSignal("Value"):Connect(function()
print("Changed")
end)
return module
Or you can fire an event every time you change the value in the first module:
The first module
local module = {}
module.value = 0 -- Value to change.
-- Event.
local be = Instance.new("BindableEvent")
module.ValueChanged = be.Event
-- Function.
local function updateValue(newValue)
module.value = newValue
be:Fire(newValue)
end
-- Calling the function.
task.wait(2)
updateValue(3)
task.wait(2)
updateValue(10)
return module
The second module
local OtherModule = require(--[[module location here]])
local module = {}
OtherModule.ValueChanged:Connect(function(value)
print("Changed")
end)
return module
The reason is because the value inside the first module is being changed before it gets returned, so the events are not firing when the module gets required. Inside the first module you can put the value updates inside a task.spawn() function.
And the second module needs to be required by a script so you can see the results.
Any time you update the value in the first module after it has been required, and after the second module has been required (not by the first module), you will see a print message, as well.
This is what I found so confusing, the fact that the third script needed to require the 2nd module script, despite the script itself being empty aside from the require code. Thank you for all your help