It looks like youâre doing this locally per player as you have a debounce âffâ thatâs not defined? If so, youâll need to do this on the server as youâre instantiating a GameObject that wonât be replicated from client->server.
Using the variables in your code, a server implementation of this would be:
-- globals
local DEBUG = true --> Change to 'false' to stop displaying the Region3 as a red part
-- main
local region = Region3.new(Vector3.new(0, 0, 0), Vector3.new(20, 20, 20))
local characters = { } --> Whitelist table for all characters currently in game
local inside = { } --> Used to check whether a character is currently inside the region
local function characterAdded(character)
local humanoid = character:WaitForChild 'Humanoid'
--> Add the player's character to our active character list
characters[#characters + 1] = character
humanoid.Died:connect(function ()
--> They're dead, so let's remove them from our active character list
for i, char in next, characters do
if char == character then
table.remove(characters, i)
break
end
end
end)
end
local function playerAdded(player)
player.CharacterAdded:connect(characterAdded) do
--> If the player already has a character let's call the characterAdded function
if player.Character then
characterAdded(player.Character)
end
end
end
game.Players.PlayerAdded:connect(playerAdded) do
--> If there are already players in the game that the event missed, let's call the playerAdded function
for _, player in next, game.Players:GetPlayers() do
playerAdded(player)
end
end
game.Players.PlayerRemoving:connect(function (player)
--> They're leaving so let's clean up our list
local character = player.Character
if character then
for i, char in next, characters do
if char == character then
table.remove(characters, i)
break
end
end
end
end)
spawn(function ()
local check = 0 --> Interatively incremented so we can tell whether they're currently in the
while true do
check = check >= 1000 and 0 or check + 1 --> You could just bitshift this, but to keep memory low, let's reset the integer every once in a while
--> First let's find all the characters that are currently within our region...
local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, characters, 1000)
for _, part in next, parts do
if part.Parent then
local humanoid = part.Parent:FindFirstChildOfClass 'Humanoid'
if humanoid then
local character = humanoid.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if player then
print(player, 'is inside')
--> They're inside, so let's give them the updated check integer
inside[player.Name] = check
--> Now let's give them a forcefield if they haven't already got one
if not character:FindFirstChildOfClass 'ForceField' then
Instance.new('ForceField', character)
end
end
end
end
end
--> Now let's look at our active list to make sure that they all have the most recent frame's check
--> if not, we'll remove them from the list, and remove their forcefield
for name, sum in next, inside do
if sum and sum ~= check then
local player = game.Players:FindFirstChild(name)
if player then
local character = player.Character
if character then
local ff = character:FindFirstChildOfClass 'ForceField'
if ff then
print(player, 'is outside')
ff:Destroy()
inside[name] = nil
end
end
end
end
end
wait(0.1)
end
end)
-- Ignore this, it's just for debug purposes for spawning the red box if 'DEBUG' variable is set to true
do
if DEBUG then
local box = Instance.new 'Part'
box.Anchored = true
box.CanCollide = false
box.Color = Color3.fromRGB(200, 50, 50)
box.Name = 'DEBUG_REGION_BOX'
box.Size = region.Size
box.CFrame = region.CFrame
box.Transparency = 0.7
box.Parent = game.Workspace
for _, surface in next, {'TopSurface', 'BottomSurface'} do
box[surface] = 0
end
end
end
Hopefully my minimal commenting will help you understand the above. If not, feel free to ask any questions. The idea is to keep track of which players are active in game, so you donât have to call :FindPartsInRegion3 on every part in that region, and instead only look for character parts. Then once you know that, you just need to keep track of who was found to be in that region in that frame and add/remove the forcefield accordingly.