How to continuously add stats to a player while they are touching a part

You can use the touched event to fire a function which then runs a loop only once by using a debounce setup and then checks with GetPartsInPart, loops through parts found and adds the players to a table which then rewards then if none found exits the loop until someone else touches the button to start it. here is example of how below but you may need to fix or change your button variables

--local buttons = game.Workspace.Buttons.MultiplierButtons
local touching = false

--[[Button variables]]
local button1 = buttons.Button1
local playersTouching = {}  -- holds table of current players touching part so can loop and award currency


local overlapParams = OverlapParams.new()
overlapParams.MaxParts = 100
local Looping  -- used to see if while loop already running
local buttonDebounce  -- used for a small delay on button debounce after a player if found

function CheckPlayer()
	if Looping then return end
	Looping = true
	while task.wait(.25) do  -- loop to check if someone in bounds
		local PartsTouching = workspace:GetPartsInPart(button1, overlapParams)
		for i, part in pairs(PartsTouching) do
			local Player = game.Players:GetPlayerFromCharacter(part.Parent) -- see if player
			if Player and not table.find(playersTouching,Player) then
				table.insert(playersTouching, Player)
			end
		end
		if #playersTouching > 0 then
			for i, player in ipairs(playersTouching) do  -- may want to wrap this in pcall and do findfirstchild on the leaderstats etc
				if player.leaderstats.Cash.Value >= button1.Config.Price.Value then  -- may need to fix this variable for button here
					player.leaderstats.Cash.Value -= button1.Config.Price.Value
					player.multiplier.Value += button1.Config.MultiToAdd.Value * (1 + player.rebirths.Value)
				end
			end
			playersTouching = {}  -- clear the table for next loop to check again 
		else
			break   -- no players touching break out of loop for now
		end
	end
	Looping = nil
end


button1.Button.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player and not buttonDebounce then
		buttonDebounce = true
		delay(.5, function()  -- reset the debounce after delay
			buttonDebounce = nil
		end)
		CheckPlayer()
	end
end)

This is probably not the most effective or efficient way to do this you might can even use overlapParams filtering etc to make it better, maybe even collection service

They should probably use if game.Players:GetPlayerFromCharacter(hit.Parent) or game.Players:FindFirstChild(hit.Parent.Name)

I used the full script you posted and it didn’t work. There are some errors that I fixed like calling the function with 2 arguments when there is only 1 parameter, but still nothing. Also I’m not sure why you grab local player since I have the script in a folder in Server Script Service.

So I tried your script and it seems like it might work, but it still has some bugs. I tried to debug it using print statements and found out that the loop in the CheckPlayer() function only runs once for some reason. I think everything else runs fine.

1 Like

Actually figured it out, just needed to change

local PartsTouching = workspace:GetPartsInPart(button1, overlapParams)

to

local PartsTouching = workspace:GetPartsInPart(button1.Button, overlapParams)

because it was getting the folder, not the base part. It works now, thanks!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.