Region3 And Zone Issues | Keycard Level Based Zones

Hello there, I’m working on an SCP game which has zones and If your Keycard Level is L0 and the Zone your in is L2 it will fire and event and if you leave then it fires another event but the code isn’t working for some reason

Expected Behaviour:
Player with L0 Keycard Level Enters L2 Level Zone and A Ui saying You are in an Unauthorized zone, you can be killed. and if the Players leaves that UI fades out

Experienced Behaviour:
Nothing happens, no logs, no errors, nothing

Code:

local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local ZoneManager = {}
ZoneManager.__index = ZoneManager

function ZoneManager.new()
	local self = setmetatable({}, ZoneManager)

	self.checkInterval = 1 -- Check every second
	self.lastCheckTime = 0
	self.zoneLevels = {
		L0 = { "L0", "L1", "L2", "L3", "L4" },
		L1 = { "L1", "L2", "L3", "L4" },
		L2 = { "L2", "L3", "L4" },
		L3 = { "L3", "L4" }
	}
	self.playersInUnauthorizedZones = {}

	return self
end

function ZoneManager:IsPlayerInZone(player, zone)
	local character = player.Character
	if not character then return false end

	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	if not humanoidRootPart then return false end

	local region = Region3.new(
		zone.Position - (zone.Size / 2),
		zone.Position + (zone.Size / 2)
	)

	-- Check if the player's humanoid root part intersects with the zone
	local partsInRegion = workspace:FindPartsInRegion3WithIgnoreList(region, { character }, 1)
	for _, part in ipairs(partsInRegion) do
		if part:IsDescendantOf(character) then
			return true
		end
	end

	return false
end

function ZoneManager:CheckZones()
	local currentTime = tick()
	if currentTime - self.lastCheckTime < self.checkInterval then
		return
	end

	self.lastCheckTime = currentTime

	-- Check for players entering unauthorized zones
	for level, zones in pairs(self.zoneLevels) do
		for _, zone in pairs(CollectionService:GetTagged(level)) do
			for _, player in pairs(Players:GetPlayers()) do
				if self:IsPlayerInZone(player, zone) then
					local keycard = player.Character and player.Character:FindFirstChild("KeycardLevel")
					if keycard then
						local keycardValue = keycard.Value
						if not table.find(zones, keycardValue) then
							if not self.playersInUnauthorizedZones[player] then
								self.playersInUnauthorizedZones[player] = true
								print("Player entered unauthorized zone:", player.Name, "Zone:", zone.Name)
								ReplicatedStorage.Remotes.UI.EnteredUnauthoirzed:FireClient(player)
							end
						end
					end
				end
			end
		end
	end

	-- Check for players leaving unauthorized zones
	for player, _ in pairs(self.playersInUnauthorizedZones) do
		local isInUnauthorizedZone = false
		for level, zones in pairs(self.zoneLevels) do
			for _, zone in pairs(CollectionService:GetTagged(level)) do
				if self:IsPlayerInZone(player, zone) then
					local keycard = player.Character and player.Character:FindFirstChild("KeycardLevel")
					if keycard then
						local keycardValue = keycard.Value
						if not table.find(zones, keycardValue) then
							isInUnauthorizedZone = true
							break
						end
					end
				end
			end
			if isInUnauthorizedZone then break end
		end
		if not isInUnauthorizedZone then
			self.playersInUnauthorizedZones[player] = nil
			print("Player left unauthorized zones:", player.Name)
			ReplicatedStorage.Remotes.UI.LeftUnauthorized:FireClient(player)
		end
	end
end

-- Initialize ZoneManager instance
local zoneManager = ZoneManager.new()

-- Connect ZoneManager CheckZones method to RunService.Heartbeat
RunService.Heartbeat:Connect(function()
	zoneManager:CheckZones()
end)

-- Initial debug print to verify script is running
print("Zone checking script started")

Keycard Location:
image

Zones:

Client code:

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage.Remotes.UI


function TweenIn()
	local TweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false , 0)
	local Tween = TweenService:Create(script.Parent.Frame.TextLabel, TweenInfo, { TextTransparency = 0 })
	Tween:Play()
end

function TweenOut()
	local TweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false , 0)
	local Tween = TweenService:Create(script.Parent.Frame.TextLabel, TweenInfo, { TextTransparency = 1 })
	Tween:Play()
end

Remotes.EnteredUnauthoirzed.OnClientEvent:Connect(TweenIn)
Remotes.LeftUnauthoirzed.OnClientEvent:Connect(TweenOut)

Also this is my first time Using OOP, I also realized I posted an old version of the Server Code at first.

Funnily enough I just replies to another post that Region3 is deprecated. Use this instead:

I actually didn’t know Region3 was Deprecated.

It didnt notifice you in the editor? Seem like Roblox forgot to do that like others deprecated methods

Yep it does not show as Deprecated in the editor.

Hey @vipkute0057, I tried updating to the New API and still isn’t working.

local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local ZoneManager = {}
ZoneManager.__index = ZoneManager

function ZoneManager.new()
	local self = setmetatable({}, ZoneManager)

	self.checkInterval = 1 -- Check every second
	self.lastCheckTime = 0
	self.zoneLevels = {
		L0 = { "L0", "L1", "L2", "L3", "L4" },
		L1 = { "L1", "L2", "L3", "L4" },
		L2 = { "L2", "L3", "L4" },
		L3 = { "L3", "L4" }
	}
	self.playersInUnauthorizedZones = {}

	return self
end

function ZoneManager:IsPlayerInZone(player, zone)
	local character = player.Character
	if not character then return false end

	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	if not humanoidRootPart then return false end

	local params = OverlapParams.new()
	params.FilterDescendantsInstances = { character }
	params.FilterType = Enum.RaycastFilterType.Exclude

	local region = zone.CFrame
	local size = zone.Size

	local partsInRegion = workspace:GetPartBoundsInBox(region, size, params)
	for _, part in ipairs(partsInRegion) do
		if part:IsDescendantOf(character) then
			return true
		end
	end

	return false
end

function ZoneManager:CheckZones()
	local currentTime = tick()
	if currentTime - self.lastCheckTime < self.checkInterval then
		return
	end

	self.lastCheckTime = currentTime

	-- Check for players entering unauthorized zones
	for level, zones in pairs(self.zoneLevels) do
		for _, zone in pairs(CollectionService:GetTagged(level)) do
			for _, player in pairs(Players:GetPlayers()) do
				if self:IsPlayerInZone(player, zone) then
					local keycard = player.Character and player.Character:FindFirstChild("KeycardLevel")
					if keycard then
						local keycardValue = keycard.Value
						if not table.find(zones, keycardValue) then
							if not self.playersInUnauthorizedZones[player] then
								self.playersInUnauthorizedZones[player] = true
								print("Player entered unauthorized zone:", player.Name, "Zone:", zone.Name)
								ReplicatedStorage.Remotes.UI.EnteredUnauthoirzed:FireClient(player)
							end
						end
					end
				end
			end
		end
	end

	-- Check for players leaving unauthorized zones
	for player, _ in pairs(self.playersInUnauthorizedZones) do
		local isInUnauthorizedZone = false
		for level, zones in pairs(self.zoneLevels) do
			for _, zone in pairs(CollectionService:GetTagged(level)) do
				if self:IsPlayerInZone(player, zone) then
					local keycard = player.Character and player.Character:FindFirstChild("KeycardLevel")
					if keycard then
						local keycardValue = keycard.Value
						if not table.find(zones, keycardValue) then
							isInUnauthorizedZone = true
							break
						end
					end
				end
			end
			if isInUnauthorizedZone then break end
		end
		if not isInUnauthorizedZone then
			self.playersInUnauthorizedZones[player] = nil
			print("Player left unauthorized zones:", player.Name)
			ReplicatedStorage.Remotes.UI.LeftUnauthorized:FireClient(player)
		end
	end
end

-- Initialize ZoneManager instance
local zoneManager = ZoneManager.new()

-- Connect ZoneManager CheckZones method to RunService.Heartbeat
RunService.Heartbeat:Connect(function()
	zoneManager:CheckZones()
end)

-- Initial debug print to verify script is running
print("Zone checking script started")

In the player in zone function, the params exclude the character, then it will detect anything outside of your character, I recommend do the opposite that is only include the character in the params and if it give result then it will always be inside of a character

Ohhhhhhhhh that would make sense

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.