Hi I am pretty new to trying Event-based programming and OOP I am still experimenting and I can’t find a way to implement a simple debounce, without having to use Wait(), Delay(), Coroutines. based on what I read about making consistent games. Event-based programming is king.
I am trying to make a bus that count’s people inside and list them in a table using modules since there’s going to be multiple bus and to avoid repeated code. My situation is when I touch the door it immediately puts me back out instead of staying inside of the bus. How can I avoid this?
local BusHandler = require(game:GetService("ServerScriptService").BusHandler)
local Trigger = script.Parent.Trigger
local TeleportInside = script.Parent.TeleportInside
local TeleportOutside = script.Parent.TeleportOutside
local PlayerEntering = false
local PlayersInside = {}
function TeleportPlayer(Character, Check)
if not Check then
BusHandler:TeleportPlayer(Character, TeleportInside)
else
BusHandler:TeleportPlayer(Character, TeleportOutside)
end
end
function AddPlayersToBus(Hit)
local CheckPlayerInside
local Player = game.Players:FindFirstChild(Hit.Parent.Name)
if Player then
if PlayerEntering then return end
CheckPlayerInside = BusHandler:CheckPlayerListed(PlayersInside, Player) --returns true or false
if not CheckPlayerInside then -- Add Player
PlayerEntering = true
PlayersInside = BusHandler:AddPlayer(PlayersInside, Player)
TeleportPlayer(Player.Character, CheckPlayerInside)
elseif CheckPlayerInside then -- Remove Player
PlayerEntering = true
PlayersInside = BusHandler:RemovePlayer(PlayersInside, Player)
TeleportPlayer(Player.Character, CheckPlayerInside)
end
end
wait(1)
PlayerEntering = false
end
Trigger.Touched:Connect(AddPlayersToBus)
Currently, I implemented the wait(n) just to show that the solution work doing this way. but I want to avoid this and how?
Using a classic debounce wouldn’t be viable for this, as the values would keep swapping depending on who is on it. So I recommend using tables. A setup like this might work:
local playersTouching = {}
part.Touched:Connect(function(hit)
if (hit.Parent:FindFirstChildOfClass("Humanoid")) then
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if (player) then
if (not playersTouching[player] == player) then
playersTouching[player] = player
-- Code
wait(1)
playersTouching[player] = nil
end
end
end
end)
The cleanest way would be to use the functions meant to handle tables, such as table.insert, table.remove and table.find, in my opinion.
Here’s an example:
local Debounces = {}
if (table.find(Debounces, Player.UserId)) -- Check if player is already in the table.
then return end -- Return end if they already exist.
table.insert(Debounces, Player.UserId) -- Add player.
table.remove(Debounces, table.find(Debounces, Player.UserId)) -- Remove player.
function busHandler:AddPlayer(PlayersTable, Player)
local CurrentTable = PlayersTable
table.insert(CurrentTable, Player.Name)
return CurrentTable
end
function busHandler:RemovePlayer(PlayersTable, Player)
local CurrentTable = PlayersTable
local Check = table.find(CurrentTable, Player.Name)
if Check then
table.remove(CurrentTable, Check)
return CurrentTable
end
end
It seems I didn’t quite portray a better explanation of the problem. As I said I need to find a way to prevent players from Listing and Un-listing immediately. Since I want the players to get inside and had to touch the door again to get out.
this is my preferred method as I don’t use wait in script
local debounceTable = {}
local function coolDown(plr, second)
if debounceTable[plr.UserId] == nil then
debounceTable[plr.UserId] = os.time()
return true
else
if os.time() - debounceTable[plr.UserId] >= second then
debounceTable[plr.UserId] = os.time()
return true
else
return false
end
end
end
if coolDown(Player, 1) then
-- do staff here
else
print("please wait for cooldown")
end
I don’t see why it would cause any issues. delay is used for, as the name implies, to delay the call of the function provided given for the given amount of seconds, without interrupting the current thread.
But that doesn’t happen. A new thread is created when the function is called. It’ll still pause for a certain amount of time before setting the player within the player array to nil.
local playerList = {}
-- Function goes here but can stil be called even when waiting
if (not playerList[player] == player) then
playerList[player] = player
-- Code
wait(2) -- Will wait
playerList[player] = nil
end