Need help fixing this Escaping Prison Region script?

Hello there. Today I am trying to make a prison escape region system. How does it work? Well basically you will spawn in the prison area with an region on it, when you exit on the region as a prisoner, you’ll be in the criminal team. That’s basically it.

So my first one was fine. It was working fine. Cause it uses one part that will act as a “Region” in the prison area.

This is what happens:

As you can see in the video, it only uses one giant part. Like I said earlier, it acts as a “Region” for the prison area. Now you can see when I exit that part, I will be on the Criminal Team. Meaning the code is fine. By the way this is the code that handles it:

local PrisonZone = workspace.Prison.PrisonZone
RunService.Heartbeat:Connect(function()
	if Player.TeamColor == InmateColor and Player.Character then
		local offset = PrisonZone.CFrame:PointToObjectSpace(Player.Character.PrimaryPart.Position)
		local ZoneHalfSize = PrisonZone.Size / 2
		if offset.x < -ZoneHalfSize.x or offset.x > ZoneHalfSize.x or offset.z < -ZoneHalfSize.z or offset.x > ZoneHalfSize.z then
			-- Fire an event to make the player into Criminal Team in server
		end
	end
end)

This code is for one Region only.

Now I tried different experiments like making it multiple parts + rotation. SpooksHD said it works for rotation which does. Now let’s get to the point!

So with multiple parts. Let’s say the Prison is very big and the walls have rotation. It requires multiple parts to act as regions. This is what I did to the code in order to register multiple parts into one code for it to handle.

The code for multiple regions:

local PrisonZone = nil
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		PrisonZone = v
	end
end

RunService.Heartbeat:Connect(function()
	if Player.TeamColor == InmateColor and Player.Character then
		local offset = PrisonZone.CFrame:PointToObjectSpace(Player.Character.PrimaryPart.Position)
		local ZoneHalfSize = PrisonZone.Size / 2
		if offset.x < -ZoneHalfSize.x or offset.x > ZoneHalfSize.x or offset.z < -ZoneHalfSize.z or offset.x > ZoneHalfSize.z then
			-- Fire an event to make the player into Criminal Team in server
		end
	end
end)

I set the variable PrisonZone to nil so I can properly loop through all the regions in one model. So it will compile it together then set the variable into “v” so it will be the parts.

Then use the heartbeat loop again to loop.

Now this is what happens:

Now I don’t know what did I do wrong. I did the for looping properly. I don’t know what else I could have missed throughout the code.

2 Likes

I think I might know what the problem is. It’s likely with how you’re setting PrisonZone in the for loop.

What’s happening, is the code will get stuck in the for loop, go through all of the parts named “PrisonZone” and make the PrisonZone switch between them, and lastly become the final part named “PrizonZone” that it lands on. Only then will it move on to the Hearbeat function - and by then, PrisonZone will only be set to one of the parts named PrisonZone, not all of them!

Another possibility on top of the first, is that it’s also getting confused between the parts named “PrisonZone”, so it doesn’t know which “PrizonZone” to pick.

The fix would be to group these parts into one main part or model to refer to everything - I’m not a big builder so there’s likely a better way to group them together.

1 Like

I select all of them. Then CTRL + G to group them into one model. Then go to the code and loop through it. Anyway what did you mean by this?

I am confused. Any more methods to fix the problem?

You’re selecting only one zone by doing

local PrisonZone = nil
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		PrisonZone = v
	end
end

If you want to select all of them you should do this instead

local PrisonZones = {}
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		table.insert(PrisonZones, v)
	end
end
1 Like

For the zone checking:

local PrisonZones = {}
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		table.insert(PrisonZones, v)
	end
end

RunService.Heartbeat:Connect(function()
	if Player.TeamColor == InmateColor and Player.Character then
         for i, v in pairs(PrisonZones) do
		      local offset = v.CFrame:PointToObjectSpace(Player.Character.PrimaryPart.Position)
		      local ZoneHalfSize = v.Size / 2
		      if offset.x < -ZoneHalfSize.x or offset.x > ZoneHalfSize.x or offset.z < -ZoneHalfSize.z or offset.x > ZoneHalfSize.z then
			-- Fire an event to make the player into Criminal Team in server
		      end
         end
	end
end)
1 Like

Just thought of an issue you might run into:

Let’s say we have 2 zones, the Zone A and the Zone B.
The code will check if you’re out of both zones, but you can be out of Zone A and be in Zone B or vice-versa.

To fix that you can use this:

IMPORTANT!!!
The code below has a few bugs in it, I’ll send a new one that has no bugs when I go back home. (I’m going to travel in an hour or so.)
Nevemind, I might send it tomorrow.

local PrisonZones = {}
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		PrisonZones[v] = {IsInZone = false}
	end
end

RunService.Heartbeat:Connect(function()
	if Player.TeamColor == InmateColor and Player.Character then
         for a, b in pairs(PrisonZones) do
		      local offset = a.CFrame:PointToObjectSpace(Player.Character.PrimaryPart.Position)
		      local ZoneHalfSize = a.Size / 2
		      if offset.x < -ZoneHalfSize.x or offset.x > ZoneHalfSize.x or offset.z < -ZoneHalfSize.z or offset.x > ZoneHalfSize.z then
                   PrisonZones[a].IsInZone = false
                   local CanChangeTeams = true
                   for c, d in pairs(PrisonZones) do
                       if c.IsInZone == true then CanChangeTeams = false end
                   end
                   if CanChangeTeams then
			-- Fire an event to make the player into Criminal Team in server
                   end
              else
                   PrisonZones[a].IsInZone = true
		      end
         end
	end
end)
2 Likes

@Giggio450BR I tried this code:

local PrisonZones = {}
for i,v in pairs(workspace.Prison.PrisonRegions:GetChildren()) do
	if v:IsA("Part") and v.Name == "PrisonZone" then
		table.insert(PrisonZones, v)
	end
end

RunService.Heartbeat:Connect(function()
	if Player.TeamColor == InmateColor and Player.Character then
         for i, v in pairs(PrisonZones) do
		      local offset = v.CFrame:PointToObjectSpace(Player.Character.PrimaryPart.Position)
		      local ZoneHalfSize = v.Size / 2
		      if offset.x < -ZoneHalfSize.x or offset.x > ZoneHalfSize.x or offset.z < -ZoneHalfSize.z or offset.x > ZoneHalfSize.z then
			-- Fire an event to make the player into Criminal Team in server
		      end
         end
	end
end)

now this is what happened:
https://streamable.com/l9ih3i

Somebody help? Both codes didn’t work. Strange.