I’m trying to a system that will detect when a player has enter or left a area. Here is my code.
local run = game:GetService("RunService")
local pos1 = script.Parent.Position - (script.Parent.Size/ 2)
local pos2 = script.Parent.Position + (script.Parent.Size/ 2)
local region = Region3.new(pos1, pos2)
local playersInRegion = {}
run.Stepped:Connect(function()
wait()
local PartsInRegion = workspace:FindPartsInRegion3(region , nil, 1000000)
for _, Part in ipairs(PartsInRegion) do
if Part.Parent:FindFirstChild("HumanoidRootPart") ~= nil then
print("Player is in region")
else
print("Player in not in region")
end
end
end)
My problem is that since the script loop through ever part that is inside the region it will say that the player is not inside the region for ever part inside the region that is not the player
I wrote a response to a response similar to this, it does essentially the same thing, in that it finds when player enter a region and when they leave it. It uses the spatial query API which should allow for rotated parts, respects geometry afaik, et cetera. It also supersedes the Region3 methods which are actually deprecated.
If you need to check every frame (this will cause more calculations to be run more frequently so I really don’t think it’s advisable), you can substitute the loop for a connection, and remove the task.wait call.
for some reason it keep saying I left and enter the part when standing just standing inside it
local players = game:GetService('Players')
local playersInPartLastIteration = {} -- players who were in the part in the last iteration
local partToCheckCollision = script.Parent
while true do
local parts = workspace:GetPartsInPart(partToCheckCollision)
local playersInPart = {} -- players who are in the part
for i,v in ipairs(parts) do -- i is the index, v is the part
local player = players:GetPlayerFromCharacter(v.Parent)
if player and not table.find(playersInPartLastIteration, player) then -- we check that they weren't in here on the last iteration to ensure this doesn't fire repeatedly every iteration
table.insert(playersInPart, player)
print("Player is in part")
end
end
-- now, we check for the players who've been removed from the part
for i,v in ipairs(playersInPartLastIteration) do -- i is index, v is player
if not table.find(playersInPart, v) then -- now, check that they were in the part on the last iteration but not this iteration
print("Player is not in part")
end
end
task.wait(0.1) -- you don't really need to check every frame, 0.1 seconds should suffice
-- finally, set the last iteration to be the result from this iteration
playersInPartLastIteration = playersInPart
end
I see, that was an oversight when I initially wrote the post, I’ll fix it after I post this.
This one should work now, it was because although the player was inside the part, it wasn’t being added to playersInPart
local players = game:GetService('Players')
local playersInPartLastIteration = {} -- players who were in the part in the last iteration
local partToCheckCollision = script.Parent
while true do
local parts = workspace:GetPartsInPart(partToCheckCollision)
local possiblePlayers = {} -- players who are in the part
for _, part in parts do
local player = players:GetPlayerFromCharacter(part.Parent)
if player and not table.find(possiblePlayers, player) then -- we check that their player hasn't been found in the part already, append to the table of possible players
table.insert(possiblePlayers, player)
end
end
for _, player in possiblePlayers do
if not table.find(playersInPartLastIteration, player) then
-- the player wasn't found in the last iteration so this is their first time in the part
print('Player entered part')
end
end
for _, player in playersInPartLastIteration do
if not table.find(possiblePlayers, player) then
-- player was found in last iteration but not this iteration so this is their first time leaving the part
print('Player left part')
end
end
task.wait(0.1) -- you don't really need to check every frame, 0.1 seconds should suffice
-- finally, set the last iteration to be the result from this iteration
playersInPartLastIteration = possiblePlayers
end
If you want to further expand on speed, you can use the player as the index and something truthy as a value for quick lookup instead of using table.find (although be sure to keep a copy of the normal table without quick lookup as it’s faster to iterate through a normal table than a dict)