Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How can I check if a player has left a region?

I currently have 2 functions, one to check when a player has left a region and one for if a new player joins the region. I'm having issues with getting it to remove the player from the table if they have left the region.

local regionPart = workspace:WaitForChild("RegionPart")
local region = Region3.new(regionPart.Position - (regionPart.Size / 2), regionPart.Position + (regionPart.Size / 2))

local playersInRegion = {}

local function addToRegion()
	for _, part in ipairs(partsInRegion) do
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent)
			table.insert(playersInRegion, player)
			
			if not player.Character:FindFirstChild("ForceField") then
				local forceField = Instance.new("ForceField", player.Character)
			end
		end
	end
end

local function removeFromRegion()
	for partIndex, part in ipairs(partsInRegion) do
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent)
			
			if not table.find(playersInRegion, player) then
				table.remove(playersInRegion, player)
				player.Character:FindFirstChild("ForceField"):Destroy()
			end
		end
	end
end

while wait() do
	partsInRegion = workspace:FindPartsInRegion3(region)
	
	addToRegion()
	removeFromRegion()
end

1 comment

0

Hmm.. ill see what i can come up with, You mind if i re-write the code?

1 answer

Just updated my Answer to only work with Regions as you asked. only took about 10 mins too lol.

How this works:

  1. the player enters the region block they get added to a global table and checks to see if player is in the table or not via addToRegion()
  2. the function named removeFromRegion() also fires but its structured in a way so it only removes players that re NOT in the region otherwise it will do nothing

The way i accomplished this is by cycling through the player parts via GetChildren() and only return true if any parts are in the region otherwise the default false will be set.

local regionPart = workspace:WaitForChild("RegionPart")
local region = Region3.new(regionPart.Position - (regionPart.Size / 2), regionPart.Position + (regionPart.Size / 2))

local playersInRegion = {}

local function addToRegion()
    for _, part in ipairs(partsInRegion) do
        if part.Parent:FindFirstChild("Humanoid") then
			local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent)
			if(table.find(playersInRegion,player) == nil) then
				table.insert(playersInRegion, player)
			end

            if not player.Character:FindFirstChild("ForceField") then
                local forceField = Instance.new("ForceField", player.Character)
            end
        end
    end
end

local function removeFromRegion()

	--// changed this for loop to cycle through the saved players instead of the parts as its easyer to check to see if they are in the region or not later in this loop
	for ind,plr in pairs(playersInRegion) do

		--// grab the character of the player...
		local Char = plr.Character

		--// a local value that i use to see if a player is in the region or not
		local InRegion = false

		--// cycle through the player BaseParts..
		for ind,CPart in pairs(Char:GetChildren()) do
			if(CPart:IsA("BasePart") == true) then
				--// if we find any part inside our region then set the above InRegion value to true and break out of this for loop
				if(table.find(partsInRegion,CPart) ~= nil) then
					InRegion = true
					break
				end
			end
		end
		--// the main guts of the remover that only turns on when the above InRegion is false
		if(InRegion == false) then	
			print("Removing player [",plr,"] from region \n and removing Forcefield!")

			--// use the index we find this player as table.remove only accepts numbers not objects as its index
			table.remove(playersInRegion, ind)

			--// remove any forcefield
			local  FF = Char:FindFirstChild("ForceField")
			if(FF ~= nil) then
				FF:Destroy()
			end
		end
	end
end

while wait() do
    partsInRegion = workspace:FindPartsInRegion3(region)

    addToRegion()
	removeFromRegion()
	table.foreach(playersInRegion,function(a,b)
		print("Player Named [",b.Name,"] is in Region!")
	end)
end

Might need to refine the functions if you plan on having npc's in your game as it may break with them anyway hope this helps! :)

3 comments

0

ugh typos galore!, oh well xD

0

I didn't really want to use the touched events because they are very inconsistent. I really wanted to see what the problem was with what I currently have.

0

just re-wrote my answer to only work with regions as you asked. Hope this helps you! :)

This discussion is preserved as it was. New answers, comments, and votes are closed.