How do you check if the player is in certain area

I know there’s a way to do this,
I have made parts and used the Touched event but that doesn’t work because when I player equips a tool it says that the player TouchEnded then Touched. I tryed using Magnitude but the areas are so close to each other it would overlap. I tryed useing math by dividing the size adding added it one the position but that only works for blocks who’s orientation is 0,0,0. I was thinking of using Region3 but isn’t that for terrain and I don’t think I could see if the player is in it.

So how should I make it?

I have been stuck in this problem for a while.

2 Likes

Region3 is for parts, not necessarily terrain. The way you’d check to see if players are inside is by looping every second or so, and every time you loop you iterate through all of the parts in workspace:FindPartsInRegion3(region), retreiving the player from the parts if possible.

If this is only based on regions as a plane, as in, not a 3d shape like a sphere or a cuboid, you could use a point in polygon algorithm.

But region3 is for squares and I have a area that’s shaped as a wedge.

I don’t know trigonometry or calculus yet so if it’s that really science stuff I’ll need someone to explain it to me. Send link of it.

I don’t have any direct source, but it doesn’t require either of those. There’s really clever and efficient algorithms for this if you search for “Point in polygon algorithm” on google. I don’t know how it works to a point where I’m confident to explain how it works, sorry.

1 Like

A simple way to detect if players are in certain areas can be achieved by using part:GetTouchingParts(), this returns a list of all colliding parts based off of the actual hitbox of the part.

If you fill each region with can-collide false parts, you can use this method to find all players who are colliding with it, you can use that to carry out an action on all players within that region. Not sure exactly how intensive this is, but I assume not very. You could have a loop to do this, or just carry out the check when necessary.

Here’s a sample of the code you could use:

script.Parent.Touched:Connect(function()end) -- Can-collide false parts need a TouchInterest

local function getCollidingPlayers(part)
	local colliding = {}
	for _,obj in pairs(part:GetTouchingParts()) do
		local plr = game.Players:GetPlayerFromCharacter(obj.Parent) -- Check if colliding part is a character's part
		local found = false
		for _,cPlr in pairs(colliding) do -- Make sure they're not already in the list
			if cPlr == plr then
				found = true
				break
			end
		end
		if not found then
			table.insert(colliding,plr) -- Add them to the list
		end
	end
	return colliding
end

while wait(0.2) do
	local colliding = getCollidingPlayers(script.Parent)
	if #colliding > 0 then
		for _,plr in colliding do
			-- Do stuff to all colliding players
		end
	else
		-- No one is colliding
	end
end

Here’s a sample place I used to check how well the collisions worked with this method:
GetTouchingParts Example.rbxl (15.1 KB)

8 Likes

I’ll try but I am sure it will have the same problem as with the Touch event. Where whenever I equip a tool it retouches it and that’s a problem with the code I am working with.

Ah, I see. You only want an action to be carried out once each time a player enters a zone. You can still use the method, but you will have to carry it out another way. I’m only on mobile now so can’t really help.

Here’s what I’d do: create a master table, if someone’s not in it but they are in the colliding table then they have entered the area (carry out the action here and add them to the master table). If someone is in the main table but not in the collisions table then they must’ve left the region (carry out the leaving action if there is one and remove them from the master table), hope this helps, I’ll be able to provide some code tomorrow.

Ok after about a hour I Cebu up with this diagram. Is this what you mean and if not will it work anyway?

the two inPoint values are not the same because I measured it with my best guess and a red stripe. But it’s simi actuate. This is what you mean right? (edited(this does not work)

3 Likes

If your polygon is convex, you can just loop over the lines making up the polygon, and check that the point is on the same “side” of all of these lines. Check this diagram for example:

image

If you compute that the green point is on the “blue” side of every of the 3 lines making up the polygon, then you can conclude the green point is inside the polygon.

Note again, this only works for convex polygons, but if your polygons can only ever be convex (i.e. they are always either squares, rectangles, any triangle, uniform n-gons, or trapeziums), then you don’t need a more complicated algorithm.

This is extendable to 3d convex meshes too: just do the “is it on the right side” check for each face of the mesh

For a more sophisticated algorithm that handles arbitrary polygons, see here:

7 Likes

How do I find out if it’s on the blue side? Should a take the position of the area part and use :toObjectSpace?

Each line has 2 points, from there you can create a CFrame for each line that lies on the line and points toward the blue direction, and then you can transform the green dot to the object space of that CFrame. Then it should be as simple as checking if that transformed dot has a negative Z position.

4 Likes

won’t my idea take less code using magnitude?

I don’t think that method works for arbitrary convex shapes, only for a subset of them.

Yeah but all I have is Wedges and Parts.

There’s your problem. :stuck_out_tongue: I believe your code only works for equilateral convex shapes.

Wedges are only haft a square so could i not just take away one of the corners?

I’ve decided to spend a bit of time and came up with this solution for detecting players in a region using part:GetTouchingParts(). It works in the way I proposed earlier in this thread, all the code is available in the place in ServerScriptService. Players can only be in one region at a time (there’s no spam if they are in 2 regions) and there is a place to put your code for when players enter and leave regions (which fires only when they actually enter and leave).

Here’s the place: Region Test.rbxl (16.5 KB)

I hope this helps, it saves you having to do complicated maths to detect players within an irregularly shaped region.

6 Likes

Thanks but I already finished the code.