Zoning and Checking if player is inside a "zone"

I need some advice, tips or some tricks to how someone could go about handling when a player enters a zone, leaves a zone, etc, especially zones that are shaped with complex structure, without having .TouchEnded fired or any other issues.


The crude diagram should help .,.,.,.,., :grimacing:

Its really early in the morning so apologies if its confusing.

Maybe use :FindPartsInRegion3 for every shape

1 Like

Would this be performant? I am not entirely sure.

Unless you use it very much (eg for calculating damage for an explosion that happens very frequently) its not that much of a problem

I used it for a door mechanic

1 Like

I see, thank you
a;lsdka;ldajkda

Does this even detect if something leaves?

1 Like

heart beat function would probably work

1 Like

the easiest way to do this would be to brute-force check if the point is in any of the parts bounding box like this

local function isPointInArea(point: Vector3, parts: {BaseParts}): boolean
  for _, part in parts do
    local localPoint: Vector3 = part.CFrame:pointToObjectSpace(point)
    -- inverses the point`s world coordinate to a local coordinate (basically CFrame:Inverse() * vector3)

    local size: Vector3 = part.Size / 2
    -- we are going to divide it by 2 since its centered at its cframe as it extends in both directions

    if math.abs(localPoint.X) <= size.X and math.abs(localPoint.Y) <= size.Y and math.abs(localPoint.Z) <= 
    size.Z then return true end
    -- we take the absolute value of each local axis so we can compare against the positive half-size
    -- this way we account for both negative and positive directions from the part`s center

    return false
end
1 Like

Very interesting Ill explore this solution in a bit, i appreciate the help very much.

Maybe take advantage of any framework you got in the game and use it to constantly check distances between the player and the zones to get the closest one, and as a second check, you could set a specific límit distance (zone.Size.X/2) and if the distance between the player and the zone is greater than that distance the code wont consider you’re inside of it.

Possibly not the greatest method, but I dont know much about optimizations so here is what I know :sweat_smile:

I could also try to do this, I am just weary of checking every part constantly with loops or runservice connections for performance reasons, but theres also the issue of the touch giving me issues too.

1 Like

Maybe you could merge both methods, add some invisible barrier that, when touched, it will do the distance check once.

Just throwing ideas I get in the moment, there are various other methods that I dont have knowledge of.

1 Like

Hey!

Apparently you’re using parts for your zone system and checking if a player got inside of an area by using the .Touched() event., and wants to make sure that if a player leaves a certain zone box ( part ) the .TouchEnded event doesn’t cause problems if the player is in another zone.

If what i just described is correct then a way you can go about this is by checking which zone boxes the player is in contact inside of the .TouchEnded(), if the player is in contact with a zone box then it means he joined another area and you shouldn’t do any changes.

The same applies for the .Touch() event, where you can see if the zone the player was before touching is the same as the one he just joined, if so then we don’t change anything.
This means that the whole part of changing zones ( changing fog, lightning and so on ) would be handled inside of the .Touch() event.

For the code part i can only give a little help.

-- Function to get the zones
-- Pass any of the player character body parts ( like the HumanoidRootPart )
function GetTouchingParts(Part: BasePart): {BasePart} -- This is needed so we can detect touch with non-collidable parts ( for some reason :GetTouchingParts() can't get them )
	local Connection = Part.Touched:Connect(function() end)
	local Results = Part:GetTouchingParts()
	Connection:Disconnect()
	return Results
end

-- Maybe functions like workspace:GetPartsInPart() can work but i'm not sure

I’m glad if i was of any help!

1 Like

The reason why touchended causes issues is if a zone is intersecting, it can cause multiple fires and sometimes the game will think that they are not in another zone due to leaving another zone that was intersecting,

It doesnt have to be intersecting just right up against eachother causes this issue too.

But your script tidbit does seems like a solution to the problem so.

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