A zone which provide player forcefield and break it when player leave

Simply put, this is a script that create a boundary region, where as long as player is inside this region. They’re safe from any damage until they leave the region.

At first, i tried to use a non-collideable part surrounding the boundaries to check whenever the player leave or enter the region. But i find it too much of a hassle and less flexible. Then i turn to use region3, using past experience of 2 year ago, hopefully also train my skill of using region3. Whoops, its already deprecated nowaday (Wonder why). And then i heard there’s the new region3 called WorldRoot:GetPartBoundsInBox()

  • Is there any way i can improve this already working code? or a suggestion of optimization? If possible i want to look for a way that the code only run whenever a new part entered the region, so i dont have to constantly checking. But i dont think this code is performance heavy.

  • Also i have issue regarding blacklisting part that are inside the region but are native to it. Like a building, the script below doesn’t properly blacklist the part. Anyone know why?

local Players = game:GetService("Players")

-- Region constructor
local boxPos = CFrame.new(1, 19, 14)
local boxSize = Vector3.new(32, 16, 32)

-- Blacklisting the part native to the region
local blacklist = workspace.SpawnArena:GetChildren()
local params = OverlapParams.new(blacklist,Enum.RaycastFilterType.Exclude)

-- Table for storing player
local protectedplayer = {}

local function createForcefield(parent)
	local f = Instance.new("ForceField")
	f.Parent = parent
	
	return f
end

while true do
	-- Yes. This constantly check.
	local Parts = game.Workspace:GetPartBoundsInBox(boxPos,boxSize,params)
	
	for i,part in pairs(Parts) do
		local model = part.Parent
		if model:FindFirstChild("Humanoid") and Players:GetPlayerFromCharacter(model) and not model:FindFirstChild("ForceField") then
			-- Insert the player character to a table to track whoever inside the region. And later to track who left the region
			if not protectedplayer[model.Name] then
				
				protectedplayer[model.Name] = model
				
				local forcefield = createForcefield(model)
			end
		end
	end
	
	for i,player in pairs(Players:GetChildren()) do
		-- Look for every player character to crosscheck who's inside the region with the outsider
		local character = player.Character
		
		if not character then continue end
		
		if not table.find(Parts,character.HumanoidRootPart) and protectedplayer[character.Name] then 
			-- Destroy forcefield for player outside boundaries
			if character:FindFirstChild("ForceField") then
				character.ForceField:Destroy()
				protectedplayer[character.Name] = nil
				print("huzzah")
			end
		end
	end
	
	task.wait()
end

There is a good model to use for any zone in your games it’s called ZonePlus+ and let me tell you it makes it so much easier.

Oh, yeah, forgot to mention, i do aware of that zonePlus model, since i came across with it alot during research. But i take pride with my own self-made script (as for now), as it help give me insight on how it work and stuff.

Im not againts using free model and community resource, as i do use it from time to time. But for this particular scenario, im looking for self-improvement, so i made my own code of it.

Thanks for that regardless.

Ooh really well I can’t really say much about your scipt since it seams to work perfectly I created my own miny script to just show you the power of this module.

local Zone = require(game:GetService("ReplicatedStorage").Zone)
local ZonePart = workspace.ZonePart

local ForceFeildZone = Zone.new(ZonePart)

local PlayersForceFeild = {}


ForceFeildZone.playerEntered:Connect(function(player : Player)
	
	if PlayersForceFeild[player] then return end
	local Character = player.Character or player.CharacterAdded:Wait()
	
	local NewForceFeild = Instance.new("ForceField")
	NewForceFeild.Parent = Character
	PlayersForceFeild[player] = NewForceFeild
	
end)

ForceFeildZone.playerExited:Connect(function(player : Player)
	if not PlayersForceFeild[player] then return end
	PlayersForceFeild[player]:Destroy()
	PlayersForceFeild[player] = nil

end)

:+1:

1 Like