Trying To Detect When The Rootpart of a Player Leaves a Certain Zone

Hello,
So I’m trying to make a zone system using UserId’s to detect when a player is in a zone or not and ease of use with checking for it with other scripts.

And it functions properly, I just have no idea how to detect when the rootpart of said player is no longer in the part.

:GetPlayerByUserId(id).Character?

Here’s the script:

local zoneFolder = workspace.Zones

local zone = {}

zone.Zones = {}

-- make a table iteration for every zonepart that exists
function zone:indexZones()
	for _, zonePart in pairs(zoneFolder:GetChildren()) do
		if not zonePart:IsA("BasePart") then return warn("zonePart", tostring(zonePart), "Doesn't Exist.") end

		self.Zones[zonePart.Name] = {}
	end
end

function zone:updateZones(plr)
	for _, zonePart in pairs(zoneFolder:GetChildren()) do		
		local boundBox = workspace:GetPartsInPart(zonePart)

		for _, partInBox in pairs(boundBox) do
			if partInBox.Name == "HumanoidRootPart" then
				local player = game:GetService("Players"):GetPlayerFromCharacter(partInBox.Parent)

				if player then
					self.Zones[zonePart.Name] = {
						player.UserId
					}
				end



				end
			end
		end
	end
end

return zone

Any help is greatly appreciated! If you need more info, Don’t hesitate to ask!

1 Like

You can detect if player isn’t inside the zone anymore like this:

function zone:updateZones(plr)
	for _, zonePart in pairs(zoneFolder:GetChildren()) do		
		local boundBox = workspace:GetPartsInPart(zonePart)
		local playersInside = self.Zones[zonePart.Name] -- stores players in zone last time the function was called
		self.Zones[zonePart.Name] = {} -- clears table
		for _, partInBox in pairs(boundBox) do
			if partInBox.Name == "HumanoidRootPart" then
				local player = game:GetService("Players"):GetPlayerFromCharacter(partInBox.Parent)

				if player then
					table.insert(self.Zones[zonePart.Name], player.UserId) 
					-- works with multiple players in zone
				end
			end
		end
		for _,newPlr in pairs(playersInside) do-- check if any player left the zone
			if not table.find(self.Zones[zonePart.Name], newPlr) then
				print(newPlr.."has left "..zonePart.Name) -- player left zone
			end
		end
	end
end
1 Like

You could use the Touched and TouchEnded events of the BasePart class, which are fired when a part starts and stops touching another part, respectively.

Try this>>

local zoneFolder = workspace.Zones

local zone = {}

zone.Zones = {}

function zone:indexZones()
	for _, zonePart in pairs(zoneFolder:GetChildren()) do
		if not zonePart:IsA("BasePart") then return warn("zonePart", tostring(zonePart), "Doesn't Exist.") end

		self.Zones[zonePart.Name] = {}

		zonePart.Touched:Connect(function(hit)
			local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
			if player then
				self.Zones[zonePart.Name][player.UserId] = true
			end
		end)

		zonePart.TouchEnded:Connect(function(hit)
			local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
			if player then
				self.Zones[zonePart.Name][player.UserId] = nil
			end
		end)
	end
end

return zone