I'm making a custom Dialog module that I'm using in other scripts in my place. It is called DialogHandler. It sends dialog and possible responses to the player, who then responds to the dialog. This is always going to be non-instantaneous because the player is never going to be able to respond to the dialog instantaneously.

I would like to implement a function:

function DialogHandler:GetPlayerResponse(Player)

that I can use in other scripts to get a response from a player after sending them a dialog tree, like this:

DialogHandler:SendDialogTree(player, "Name", "DialogTreeName") -- sends the dialogue tree with name DialogTreeName to the player
	
local Response = DialogHandler:GetPlayerResponse(player) -- get the player's response
	
if Response == "Yes" then
	-- do stuff
elseif Response == "No" then
	-- do stuff
else end

I could just wait() until the Response is a non-nil value however that would probably disrupt the flow of the other functions of the module and be too inefficient to be practical. Instead I'd like to use coroutines as my assumption is that is the most efficient possible way.

I've already tried this:

function DialogHandler:GetPlayerResponse(Player)
	local Response
	local Thread = coroutine.create(function() 
		coroutine.yield() 
		return Response 
	end)	
	
	coroutine.resume(Thread)
	
	SendResponse.OnServerEvent:Connect(function(P, R) -- SendResponse is a RemoteEvent fired by the client when player P sends response R
		if P == Player then
			Response = R
			coroutine.resume(Thread)
		end
	end)
end

However it seems that it just returns nil in all cases. What am I missing? Thanks for your help.

EDIT:

This is the "wait()" approach I tried. It works but again it might be too inefficient to be practical.

function module:GetPlayerResponse(Player)	
	while not PlayerResponses[Player] do 
		wait(1)
	end
	
	-- PlayerResponses[Player] becomes a non-nil value when the player responds, this is handled by a separate event connection

	local R = PlayerResponses[Player]
	PlayerResponses[Player] = nil
	
	return R	
end

3 comments

0

You shouldn't put events in functions as they are asynchronous.

0

So I'd use RemoteFunctions instead?

0

No, just don't put the OnServerEvent inside the function, make it its own code block.