Region3 not working correctly

Hello! I am making a simple script where if the player is inside of a part it prints something every second (obviously I would add to this but I encountered a bug), here is the script.

local safeZone = workspace.SafeZone
local min = Vector3.new(safeZone.Position.X-safeZone.Size.X/2, safeZone.Position.Y-safeZone.Size.Y/2, safeZone.Position.Z-safeZone.Size.Z/2)
local max= Vector3.new(safeZone.Position.X+safeZone.Size.X/2, safeZone.Position.Y+safeZone.Size.Y/2, safeZone.Position.Z+safeZone.Size.Z/2)

local safeZoneRegion = Region3.new(min, max)
while true do
	wait()
	local parts = workspace:FindPartsInRegion3(safeZoneRegion, safeZone, 1000)
	for i, part in pairs(parts) do
		if part.Parent:FindFirstChild("Humanoid") ~= nil then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			print(player.Name .. " in zone and added score point.")
			wait(1)
		end
	end
end

As you can see I am using Region3, my issue is that when the player walks out of the zone sometimes it will keep printing and I am confused as to why.

Could anyone help? Thank you!

change this

if part.Parent:FindFirstChild("Humanoid") ~= nil then

to this

if part.Parent:FindFirstChild("Humanoid") then

Thank you for replying, it unfortunately did the same thing:

local safeZone = workspace.SafeZone
local min = Vector3.new(safeZone.Position.X-safeZone.Size.X/2, safeZone.Position.Y-safeZone.Size.Y/2, safeZone.Position.Z-safeZone.Size.Z/2)
local max= Vector3.new(safeZone.Position.X+safeZone.Size.X/2, safeZone.Position.Y+safeZone.Size.Y/2, safeZone.Position.Z+safeZone.Size.Z/2)

local safeZoneRegion = Region3.new(min, max)
while true do
	wait()
	local parts = workspace:FindPartsInRegion3(safeZoneRegion, safeZone, 1000)
	for i, part in pairs(parts) do
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			print(player.Name .. " in zone and added score point.")
			wait(1)
		end
	end
end

use this for loop and see what happens?

for i, part in pairs(parts) do
		if part.Parent:FindFirstChild("Humanoid") then
		        
			print(part.Parent.Name .. " in zone and added score point.")
			wait(1)
		end
	end

This is probably because you’re waiting a second each time you check a part inside the region. If you had 5 of your bodyparts inside the region, then it would check the first part, wait a second, check the second part, wait another second, etc.

That is genius! It makes total sense, but how would I make it wait because I only want it to do the action every second.

Put the wait(1) outside of the for loop, and you can remove the wait() on the 2nd line of the while loop. You should also probably add a check to see if the player already received a point for that region iteration (if you have 5 bodyparts in the region, then you would be getting 5 points per second)

Don’t do that the loop will then crash his game if you remove the wait().

It won’t crash if you put the wait(1) outside of the for loop

Try this:

local safeZone = workspace.SafeZone
local min = Vector3.new(safeZone.Position.X-safeZone.Size.X/2, safeZone.Position.Y-safeZone.Size.Y/2, safeZone.Position.Z-safeZone.Size.Z/2)
local max = Vector3.new(safeZone.Position.X+safeZone.Size.X/2, safeZone.Position.Y+safeZone.Size.Y/2, safeZone.Position.Z+safeZone.Size.Z/2)
local flag = false
local player = nil

local safeZoneRegion = Region3.new(min, max)
while wait() do
	local parts = workspace:FindPartsInRegion3(safeZoneRegion, safeZone, 1000)
	for i, part in pairs(parts) do
		if part.Parent:FindFirstChild("Humanoid") then
			player = game.Players:GetPlayerFromCharacter(part.Parent)
			flag = true
			break
		end
	end
	wait(1)
	if flag == true then
		flag = false
		print(player.Name .. " in zone and added score point.")
	end
end

Yes it does not crash. It works, but as you said I need to add a debounce because it prints like 16 times. Any idea on how I should do that?

Looks great but the only problem is that it doesn’t pass through my player variable, and I need that for adding the point.

I would probably make a table with all the players that have already been checked and only award the point if the player wasn’t already in the table

Something like this maybe (haven’t tested it):

local safeZone = workspace.SafeZone
local min = Vector3.new(safeZone.Position.X-safeZone.Size.X/2, safeZone.Position.Y-safeZone.Size.Y/2, safeZone.Position.Z-safeZone.Size.Z/2)
local max= Vector3.new(safeZone.Position.X+safeZone.Size.X/2, safeZone.Position.Y+safeZone.Size.Y/2, safeZone.Position.Z+safeZone.Size.Z/2)

local safeZoneRegion = Region3.new(min, max)
local checked = {}
while true do
	local parts = workspace:FindPartsInRegion3(safeZoneRegion, safeZone, 1000)
	for i, part in pairs(parts) do
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			if player and not checked[player] then
				checked[player] = true
				print(player.Name .. " in zone and added score point.")
			end
		end
	end
	for i in pairs(checked) do
		checked[i] = nil
	end
	wait(1)
end
1 Like

Seems to work perfect, thank you!