Need help with tracking multiple players in a script that only tracks one player

I will try to explain what my script is and my problem clearly. So I have a sword fight arena. Players get a sword when they enter then lose the sword when they leave. I did it using a Region3 on the sword fighting arena which checks for a torso. It gives the player whose torso it is a sword in their backpack, then waits for there to no longer be a torso in the Region3; when there’s no longer a torso it checks their backpack and character for the sword then deletes it.

It works perfectly fine when you do it singleplayer. The problem is with multiple players. It only does it for 1 player. it only checks for 1 torso. The script only gives 1 person a sword then takes it away from that one person. IDK how to check for multiple torsos. Do I make a table of all the parts called Torso in the Region3 then run the script for each one? I have no clue how to do that. I’m a noob, I just started getting into scripting a few days ago

I will share my script but it is very messy and I am a noob. please be nice.

Also note that there is a RemoteEvent and Localscript connected to that. it just checks LocalPlayer for the sword in their inventory and I don’t think it’s necessary to include it because it works fine.

--Initialization
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local playerservice = game:GetService("Players")
local hitbox = game.Workspace.SFArena.SFArenaHitbox
local hitboxPoint1 = hitbox.Position - Vector3.new(hitbox.Size.X/2,hitbox.Size.Y/2,hitbox.Size.Z/2)
local hitboxPoint2 = hitbox.Position + Vector3.new(hitbox.Size.X/2,hitbox.Size.Y/2,hitbox.Size.Z/2)
local region = Region3.new(hitboxPoint1, hitboxPoint2)
local toolbin = game.ServerStorage.Foil
local debounce = false

--RemoteFunction
local RemoteFunction = ReplicatedStorage:WaitForChild("FetchBackpackChecks")

playerservice.PlayerAdded:Connect(function(player)
	
	function fetchbackpackchecks()
		local shouldgiveplayertool = false
		shouldgiveplayertool = RemoteFunction:InvokeClient(player)
		
		if shouldgiveplayertool == true then
			toolbin:Clone().Parent = player.Backpack --gib to player :)
		end
		
	end
	
	function deletetool()
		if (player.Backpack:FindFirstChild("Foil") ~= nil) then
			player.Backpack:FindFirstChild("Foil"):Destroy()
		else
			player.Character:FindFirstChild("Foil"):Destroy()
		end
	end
	
end)

--Function

while true do
	
	wait()
	
	if debounce == false then
		
		local debounce = true
		
		local regionIgnoreParts = {
			game.Workspace.SFArena.SFArenaHitbox,
			game.Workspace.SFArena.HitboxVisual,
			game.Workspace.SFArena.SFArenaFloor
		}
		local regionparts = game.Workspace:FindPartsInRegion3WithIgnoreList(region, regionIgnoreParts, 20)
		
		for i,v in pairs(regionparts) do
			
			if v.Name == ("Torso") then

				local humanoid = v.Parent:FindFirstChild("Humanoid")
				local player = v.Parent
				
				if (humanoid ~= nil) then
					
					fetchbackpackchecks()
					
					--Checking if player departed hitbox and remove tool begins--
					local torsostillexists = false
					local torsodeparted = false
					repeat
						wait() 
						regionparts = game.Workspace:FindPartsInRegion3WithIgnoreList(region, regionIgnoreParts, 20)
						torsostillexists = false
						for i,v in pairs(regionparts) do
							if v.Name == ("Torso") then
								torsostillexists = true
							end
						end
						if torsostillexists == false then
							torsodeparted = true
						end
					until torsodeparted == true
					deletetool()
					--Checking if player departed hitbox and remove tool ends--
					
				end

			end
			
		end
		
		wait()
		local debounce = false
		
	end
	
end

Perhaps, just giving ideas here, you can use the .Touched and .TouchEnded functions to handle these events than a Region 3 check could.

So you could give a player a weapon, and then once any player left the zone, check if they have a sword in their backpack, and delete it.

Example:

script.Parent.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Checking if a player touched the box
	if player then
		if player.Backpack:FindFirstChild("Sword") == nil then -- Checking if the player already owns the weapon.
			local sword = script.Sword:Clone() -- Giving the player the weapon.
			sword.Parent = player.Backpack
		end
	end
end)

script.Parent.TouchEnded:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Checking if a player went out of the box.
	if player then
		local sword = player.Backpack:FindFirstChild("Sword")
		if sword then -- Checking if the player owns the weapon.
			sword:Destroy() -- Removing the weapon
		end
	end
end)
1 Like

Thank you for the suggestion, I really appreciate the effort. That’s how my script used to be, I used to be using touch events instead of Region3. The problem is that TouchEnded is extremely inconsistent and goes off when a player jumps, equips a gear, or does an emote like /e dance, even though the player is still touching the part. TouchEnded constantly fires for no reason. That’s why I had to use Region3 instead. It’s ok though because after a few hours I changed my script and it works now.

My solution was changing my script from being a server script that asks a localscript for local-only stuff through a remotefunction to the opposite. I changed it to a localscript that asks a server script for server-only stuff through a remotefunction.

Glad I could help! Keep in mind though that Region3 could lag the game with too many functions, so try to optimize it as much as you can.

1 Like