How to detect when a player is in a Region3?

Hi everyone, I’m making an obby game in which there are no stages, but there is a “skip stage” product (doesn’t really make sense but don’t worry lol). In order to know what stage the player is in, I’m using Region3.

I now need a script that, when I press a Ui Button, will tell me what region the player is in (there are 10 regions) and will bring up the right DevProduct depending on what region the player is in.

I hope I made myself as clear as possible since this problem is slightly hard to explain.

Here is some sort of script I made that creates the Regions and prints whenever a player is in Region1:


local Region1 = Region3.new(Vector3.new(-12.735, 31.292, 72.565),Vector3.new(86.265, 130.289, 171.565))
local Region2 = Region3.new(Vector3.new(-12.735, 131.292, 72.565),Vector3.new(86.265, 230.289, 171.565))
local Region3 = Region3.new(Vector3.new(-12.735, 231.292, 72.565),Vector3.new(86.265, 330.289, 171.565))
local Region4 = Region3.new(Vector3.new(-12.735, 331.292, 72.565),Vector3.new(86.265, 430.289, 171.565))
local Region5 = Region3.new(Vector3.new(-12.735, 431.292, 72.565),Vector3.new(86.265, 530.289, 171.565))
local Region6 = Region3.new(Vector3.new(-12.735, 531.292, 72.565),Vector3.new(86.265, 630.289, 171.565))
local Region7 = Region3.new(Vector3.new(-12.735, 631.292, 72.565),Vector3.new(86.265, 730.289, 171.565))
local Region8 = Region3.new(Vector3.new(-12.735, 731.292, 72.565),Vector3.new(86.265, 830.289, 171.565))
local Region9 = Region3.new(Vector3.new(-12.735, 831.292, 72.565),Vector3.new(86.265, 930.289, 171.565))
local Region10 = Region3.new(Vector3.new(-12.735, 931.292, 72.565),Vector3.new(86.265, 1030.289, 171.565))

while true do
	wait(1)
	local partsInRegion = workspace:FindPartsInRegion3(Region1, part, 1000)
	for i, part in pairs(partsInRegion) do
		if part.Parent:FindFirstChild("Humanoid") then
			print("Player found in region: "..part.Parent.Name)
		end
		
	end
end

What is the problem with your current script? It seems like it should work. Are there any errors?

1 Like

Oh that script works fine. It defines the different regions. I guess I don’t really have a problem, but I need help with how to go about doing this with the region:

I now need a script that, when I press a Ui Button, will tell me what region the player is in (there are 10 regions) and will bring up the right DevProduct depending on what region the player is in.

I know this sounds like I’m asking for someone to do it for me, but I just need help on how to get started with it because I’m not sure… :slight_smile:

I’m no expert scripter by any means, so take this with a grain of salt.
I suggest you search up how to put creator products into a ui, then since the Vector3 system is already finished you just link the “checkpoint” you are in with a new Cframe (wich is the next spawnpoint)
And I’m sure there are plenty of tutorials on obby stage skips.

1 Like

You could loop through each region with a for loop and check if they’re in that region. That’ll be a lot easier if you keep your regions in a table. Do you know how to do that or would you like help with it?

@ThanksRoBama I’ll try on my own but will probably need help lol :joy:

What I especially need to know is how to check if they are in that region.

You already got it with the code you posted, just do that for each region3, but in a loop so you don’t have to type it out

1 Like

hey @ThanksRoBama, so far I’ve come up with the following script (see below). How do I get it to check in which region the player is as fast (and compact) as possible?

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local Regions = {
	Area1 = Region3.new(Vector3.new(-12.735, 31.292, 72.565),Vector3.new(86.265, 130.289, 171.565));
	Area2 = Region3.new(Vector3.new(-12.735, 131.292, 72.565),Vector3.new(86.265, 230.289, 171.565));
	Area3 = Region3.new(Vector3.new(-12.735, 231.292, 72.565),Vector3.new(86.265, 330.289, 171.565));
	Area4 = Region3.new(Vector3.new(-12.735, 331.292, 72.565),Vector3.new(86.265, 430.289, 171.565));
	Area5 = Region3.new(Vector3.new(-12.735, 431.292, 72.565),Vector3.new(86.265, 530.289, 171.565));
	Area6 = Region3.new(Vector3.new(-12.735, 531.292, 72.565),Vector3.new(86.265, 630.289, 171.565));
	Area7 = Region3.new(Vector3.new(-12.735, 631.292, 72.565),Vector3.new(86.265, 730.289, 171.565));
	Area8 = Region3.new(Vector3.new(-12.735, 731.292, 72.565),Vector3.new(86.265, 830.289, 171.565));
	Area9 = Region3.new(Vector3.new(-12.735, 831.292, 72.565),Vector3.new(86.265, 930.289, 171.565));
	Area10 = Region3.new(Vector3.new(-12.735, 931.292, 72.565),Vector3.new(86.265, 1030.289, 171.565));
	
}

script.Parent.MouseButton1Click:Connect(function()
	
	for i, v in pairs(Regions) do
		
	end
end)

Something like this:

script.Parent.MouseButton1Click:Connect(function()
	local currentAreaName
	local currentRegion3

	for areaName, areaRegion3 in pairs(Regions) do
		local partsInRegion = workspace:FindPartsInRegion3(area_region, nil, 1000)
		for _, part in pairs(partsInRegion) do
			local character = part.Parent
			if game.Players:GetPlayerFromCharacter(character) == player then
				currentAreaName = areaName
				currentRegion3 = areaRegion3
				break
			end
		end
	end

	if currentAreaName then
		print( ([[Is in area "%s" which has region %s.]]):format(currentAreaName, currentRegion3) )
	else
		print ("Is not in any area.")
	end
end)

[/quote]

1 Like

I would suggest using Parts to represent the areas instead of hardcoding them like that. It’s easier to change, less error prone, and you can add or modify areas visually by working in the 3D window. I would do that like so:

local Regions = {}
for _, regionPart in pairs(game.Workspace.Regions:GetChildren()) do
    local regionCenter = regionPart.Position
    local regionLowerCorner = regionPart.CFrame:PointToWorldSpace(-regionPart.Size/2)
    local regionUpperCorner = regionPart.CFrame:PointToWorldSpace(regionPart.Size/2)
    local region3 = Region3.new(regionLowerCorner, regionUpperCorner)
    local regionName = regionPart.Name
   
   Regions[regionName] = region3 
end

That way you can still use the same code to figure out which region the player is in

Is this what you are searching for?

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local Regions = {
	Area1 = Region3.new(Vector3.new(-12.735, 31.292, 72.565),Vector3.new(86.265, 130.289, 171.565));
	Area2 = Region3.new(Vector3.new(-12.735, 131.292, 72.565),Vector3.new(86.265, 230.289, 171.565));
	Area3 = Region3.new(Vector3.new(-12.735, 231.292, 72.565),Vector3.new(86.265, 330.289, 171.565));
	Area4 = Region3.new(Vector3.new(-12.735, 331.292, 72.565),Vector3.new(86.265, 430.289, 171.565));
	Area5 = Region3.new(Vector3.new(-12.735, 431.292, 72.565),Vector3.new(86.265, 530.289, 171.565));
	Area6 = Region3.new(Vector3.new(-12.735, 531.292, 72.565),Vector3.new(86.265, 630.289, 171.565));
	Area7 = Region3.new(Vector3.new(-12.735, 631.292, 72.565),Vector3.new(86.265, 730.289, 171.565));
	Area8 = Region3.new(Vector3.new(-12.735, 731.292, 72.565),Vector3.new(86.265, 830.289, 171.565));
	Area9 = Region3.new(Vector3.new(-12.735, 831.292, 72.565),Vector3.new(86.265, 930.289, 171.565));
	Area10 = Region3.new(Vector3.new(-12.735, 931.292, 72.565),Vector3.new(86.265, 1030.289, 171.565));
}

local function GetRegion()
	for i, v in pairs(Regions) do
		if #workspace:FindPartsInRegion3WithWhiteList(v, {Player_Character_Here}) > 0 then
			return i, v --> Key, Value
		end
	end
end

script.Parent.MouseButton1Click:Connect(function()
	local Area, Value = GetRegion()
	if Area == nil then print("The player is not in these areas!") return end
end)

Thank you very much @ThanksRoBama! But what is that area_region argument in the partsInRegion variable? The output says this argument is missing (which it is lol).

Hi @focasds, how do I know which character to place in the Player_Character_Here argument?

Good point @ThanksRoBama, this is what I had come up with in the first place so I still had a Regions folder lol. Here is the script I have so far. I still have a problem with the area_region argument though :confused:

local Regions = {}

for _, regionPart in pairs(game.Workspace.Regions:GetChildren()) do
	local regionCenter = regionPart.Position
	local regionLowerCorner = regionPart.CFrame:PointToWorldSpace(-regionPart.Size/2)
	local regionUpperCorner = regionPart.CFrame:PointToWorldSpace(regionPart.Size/2)
	local region3 = Region3.new(regionLowerCorner, regionUpperCorner)
	local regionName = regionPart.Name

	Regions[regionName] = region3 
end

script.Parent.MouseButton1Click:Connect(function()
	local currentAreaName
	local currentRegion3

	for areaName, areaRegion3 in pairs(Regions) do
		local partsInRegion = workspace:FindPartsInRegion3(area_region, nil, 1000)
		for _, part in pairs(partsInRegion) do
			local character = part.Parent
			if game.Players:GetPlayerFromCharacter(character) == player then
				currentAreaName = areaName
				currentRegion3 = areaRegion3
				break
			end
		end
	end

	if currentAreaName then
		print( ([[Is in area "%s" which has region %s.]]):format(currentAreaName, currentRegion3) )
	else
		print ("Is not in any area.")
	end
end)

Ah, my mistake. It’s supposed to be areaRegion3. I type it as area_region` originally but changed it, turns out I forget one :sweat_smile:

Let me know if it works when that’s fixed

1 Like

@ThanksRoBama New error lol :joy:

Line 33: Invalid argument #3 to ‘format’ (string expected, got Region3)

This is line 33:
print( ([[Is in area "%s" which has region %s.]]):format(currentAreaName, currentRegion3) )

Nevermind it works, I just chenged the printed statement to print(player.Name…" is in "…currentAreaName)