--Module (In ReplicatedStorage) --
local module = {} module.showMSG = function(msgGUI) --< Inside the msgGUI, there's a textbutton called yes and a textbutton called no. msgGUI.Enabled = true msgGUI.Yes.MouseButton1Click:Connect(function() return true end) msgGUI.No.MouseButton1Click:Connect(function() return false end) end return module
---local script (Descendant of PlayerGui) --
local module = require(game:GetService("ReplicatedStorage").Module) script.Parent.MouseButton1down:Connect(function() local processedModule = module.showMSG(game.Players.localPlayer.PlayerGui:FindFirstChild("msgbox")) if processedModule == true then print("Yahoo!") else print("Oh Noes!") end end)
When I tested it out, it kept returning false when I called the module, when I did not even press any button. Is there a way to fix this?
Thank you.
See this thread about returning values that do not yet exist.
The return
on line 7 returns from the function on line 7, not the showMSG
function.
You can't forcibly return from another function, because that function may no longer be running (or may be recursive, etc...)
There are roughly three broad options:
Don't return until you have an answer.
This is a little awkward to do in ROBLOX for this particular case, but it's possible and not too bad with BindableEvents.
function showMSG(gui) gui.Enabled = true local event = Instance.new("BindableEvent") -- Listen for clicks local yesEvent = gui.Yes.MouseButton1Click:Connect(function() event:Fire(true) end local noEvent = gui.No.MouseButton1Click:Connect(function() event:Fire(false) end -- Await the first click local answer = event.Event:Wait() -- Stop caring about clicks to the buttons yesEvent:Disconnect() noEvent:Disconnect() -- Return the answer (`true` for Yes, `false` for No) return answer end local answer = showMSG(foo) print("Player said", answer)
Return an object that can be used to produce an answer.
The simplest way to do this is to return an event:
function showMSG(gui) gui.Enabled = true local event = Instance.new("BindableEvent") -- Listen for clicks local noEvent, yesEvent yesEvent = gui.Yes.MouseButton1Click:Connect(function() event:Fire(true) yesEvent:Disconnect() noEvent:Disconnect() end noEvent = gui.No.MouseButton1Click:Connect(function() event:Fire(false) yesEvent:Disconnect() noEvent:Disconnect() end -- Return an event. -- The caller of showMSG() must either :Wait() or :Connect() -- to get the result return event.Event end local answer = showMSG(foo):Wait() print("Player said", answer)
When you invoke showMSG
, tell it to contact you later.
This is usually the least convenient way to write code because it leads to lots of functions nested into each other, but it is an option.
function showMSG(gui, callback) gui.Enabled = true local event = Instance.new("BindableEvent") -- Listen for clicks local noEvent, yesEvent yesEvent = gui.Yes.MouseButton1Click:Connect(function() yesEvent:Disconnect() noEvent:Disconnect() callback(true) end noEvent = gui.No.MouseButton1Click:Connect(function() yesEvent:Disconnect() noEvent:Disconnect() callback(false) end end showMSG(foo, function(answer) print("Player said", answer) end)