How to turn Safezone based on a part into a Region3 Safezone

Hi,

I made a Safezone by inserting the script below into a part, which was then scaled upwards to fit the players in.

The problem is that it keeps on making my players die whenever they move in it. Therefore, I would like to know how I would base my safezone off of Region3 instead of a part.

Safezone script:

local hitbox = script.Parent


hitbox.Touched:Connect(function(touch)
	
	
	local char = touch.Parent
	
	if game.Players:GetPlayerFromCharacter(char) then
		
		
		if char:FindFirstChild("Humanoid") then
			
			char.Humanoid.MaxHealth = math.huge
			char.Humanoid.Health = math.huge
		end		
	end	
end)


hitbox.TouchEnded:Connect(function(touch)
	
	
	local char = touch.Parent
	
	if game.Players:GetPlayerFromCharacter(char) then

if char:FindFirstChild("Humanoid") then
			 if game:GetService("MarketplaceService"):UserOwnsGamePassAsync(game.Players[char.Name].UserId, 10502475)then                   ----- For Gamepass, Don't worry about it
			char.Humanoid.MaxHealth = 400      ----- For Gamepass, Don't worry about it
				char.Humanoid.Health = 400
			else
				char.Humanoid.MaxHealth = 100
					char.Humanoid.Health = 100
				end
		end		
		end
		end)

Instead of relying on regions or touched events, I would just shoot a ray down in a loop and check if what the ray hits is a part of the safe zone.

Wouldn’t that lag the server more than if I just had used regions for my safezone?

Regions are much more intensive on the server than rays will ever be. Just don’t make your rays super long and you’ll be fine.

Technically this isn’t true in some cases. Getting parts in a region3 is probably more intensive but using a region3 to check if characters’ humanoid root parts are in the region3 is much less intensive than ray casting. Here is a really cool module a fellow dev forum user made called Zone+.

If you want to use region3s only instead of both region3s and raycasting just ask and I can explain that to you.

Good luck,
PseudoPerson

Written on mobile

Sure, I’ll use region3 for my safezone. Am I going to replace the function above with something else or?

You can check if a player is within a region by assuming the player is just a point in space, like so:

local Zone = script.Parent
function WithinZone(Zone, Point)
	local ObjSpace = Zone.CFrame:PointToObjectSpace(Point)
	local ZoneSize = Zone.Size / 2

	return ObjSpace.X > -ZoneSize.X and ObjSpace.X < ZoneSize.X and
		   ObjSpace.Y > -ZoneSize.Y and ObjSpace.Y < ZoneSize.Y and
		   ObjSpace.Z > -ZoneSize.Z and ObjSpace.Z < ZoneSize.Z
end

function PlayerWithinZone(Player)
    local Character = Player.Character
    if Character then
        local Head = Character:FindFirstChild('Head')
        if Head then
            return WithinZone(Zone, Head.Position) --> true / false
        end
    end
end

This is infinitely (not literally) times more efficient than a Region3, and maybe rays? IIRC I benchmarked this VS rays, and this was much more efficient.

I’m not sure how to make this script work with my Safezone script mentioned above. My script uses a function while this script uses 2.

local RegionPart = workspace.RegionPart
local Region = Region3.new(RegionPart.Position - (0.5 * RegionPart.Size), RegionPart.Position + (0.5 * RegionPart.Size))


local Watching = {}
while true do
	wait()
	Parts = workspace:FindPartsInRegion3WithIgnoreList(Region, {RegionPart}, math.huge)
	for i,v in pairs(Parts) do
		if v.Name ~= "HumanoidRootPart" then continue end
		local Player = game.Players:GetPlayerFromCharacter(v.Parent)
		if Player == nil then continue end
		local Character = v.Parent
		local Humanoid = Character["Humanoid"]
		if Humanoid ~= nil then
			Humanoid.MaxHealth = math.huge
			Humanoid.Health = Humanoid.MaxHealth
		end
		if not table.find(Watching, v) then
			Thread = coroutine.wrap(function()
				table.insert(Watching, v)
				while true do
					wait()
					local IsIn = workspace:FindPartsInRegion3WithWhiteList(Region, {v}, math.huge)
					if #IsIn == 0 then
						Humanoid.MaxHealth = 100
						Humanoid.Health = 100
						for x,c in pairs(Watching) do
							if c == v then
								table.remove(Watching, x)
							end
						end
						coroutine.yield(Thread)
					end
				end
			end)()
		end
	end
end