ZonePlus v3.2.0 | Construct dynamic zones and effectively determine players and parts within their boundaries

If you wanted only the client to detect when entering and exiting a zone, you would instead use localPlayerEntered and localPlayerExited within a LocalScript in StarterPlayerScripts:



The playground is currently the best demo - copy and modify it where you need. You’ll likely be interested in ‘AmbientZone’:

We’re aiming to create some tutorials in the future to help out with this.

1 Like

Very neat module service! I’ve been looking for a way to reliably detect if a player is inside a set area without having to delve too much into complicated scripting for an upcoming project pertaining to the Fallout genre (for instance, I’ll be using this to detect if a player is in a radioactive zone and add rads) and some other minor projects; this module/service provides just that and reliably so.

Thanks for the module! :slightly_smiling_face:

1 Like

This is awesome! I already started making a few things which were made easier thanks to this module. :smirk:

Anyway I got a question. One of the projects I am working on is a capture point system, which is being inspired from the capture points in Star Wars: Battlefront 2. So, right now, using playerEntered and playerExited, I count the amount of players there is on the point and what teams there on, so it counts how many defenders and attackers are on the point. That way, I wanted to see if I can implement a contesting state.

The problem here is that sometimes the amount of players on either team can go to negative or , which bothers me since obviously it would benefit the other team. So far, the different scenarios where it went negative was dying and then the body parts exiting the point or when a player changes team, then dying, it counts for the other team player count, etc. I’m not really too good with scripting but… Any help, please? (All I have right now is detecting players entering and exiting, which adds or subtracts to the team count.)

Edit: I managed to fix the team changing problem, so the only problem now is when a player dies, and the body parts fall out, I think it counts as the player maybe? I think?

How safe can I feel, serverside, about the checks you’re performing?

For example, do any of these rely on client-reliant events (i.e. a client firing a .Touched event) - if not, then it won’t be suitable for me. Otherwise, incredibly cool!

Zone detection is ‘Automatic’ by default (i.e. which will almost always default to ‘WholeBody’) so that would require all character parts to leave the zone before the exited event is fired. If this doesn’t happen, can you DM me please and we can take a look to see if it’s an issue on our end.

If you would like to change the detection from whole-body to just the centre of the HumanoidRootPart, you can do:


(more info here)

All methods, and the player and localplayer events utilise Region3, RotatedRegion3 and/or Raycast checks. Only the experimental part events use touched events (combined with the new BasePart.CanTouch property), and these touched events are only ever formed if you connect to one of the zone part events (i.e. zone.partEntered or zone.partExited).

You can find further details at the Methodology page or feel free to ask here.

1 Like

Awesome - thank you!

User Story: I do a lot of anti exploit work and noclip boundary zones are the main way we use to stop people accessing unauthorized areas. So, obviously, important for it to work like this.

1 Like

Thanks for the info! - Also, if I plan on having multiple points. Would having a module script in each zone part with the capture point settings be better or will having one set of settings inside the main script be good?

It depends on the situation; I typically prefer having configurable values in one central location, however I’ve done both before and it’s ultimately up to preference.

@ForeverHD Wow this is super helpful and good job! Also I never knew you and Oblivious were brothers and that’s cool as well! :upside_down_face:

Keep up the good work and keep on developing, cheers!

1 Like

CanTouch is officially out, can’t wait for the new events

It’s been temporarily disabled again so I’ll wait until its re-release before updating the ZonePlus documentation (hopefully soon!)

Are there any performance issues we should be aware of when moving a zone around?

Really nice and well made. Keep up the good work. :+1:
Also, are there gravity zones included?

The _update method (triggered by a position change) only performs basic mathematical calculations and organisations of tables, and this is in addition to the 9(+1) cap of updates per second (which would otherwise be exceeded if you were dragging a zone part for instance), so you should be absolutely fine.

1 Like

Not in the playground but you could put together a gravity zone super easily with the workspace property and tweenservice:

local MOON_GRAVITY = 1.62 / 9.81
local DEFAULT_GRAVITY = 196.2
local TWEEN_INFO =

local Zone = require(game:GetService("ReplicatedStorage").Zone)
local zoneGroup = workspace.Your_Group_Of_Parts
local zone =

    TweenService:Create(workspace, TWEEN_INFO, {Gravity = MOON_GRAVITY}):Play()

    TweenService:Create(workspace, TWEEN_INFO, {Gravity = DEFAULT_GRAVITY}):Play()

workspace.Gravity = DEFAULT_GRAVITY

Whenever I call zone:getPlayers() I get this error,

  17:53:06.943  ReplicatedStorage.Modules.Zone.ZoneController:450: attempt to compare nil and number  -  Server - ZoneController:450
  17:53:06.944  Stack Begin  -  Studio
  17:53:06.945  Script 'ReplicatedStorage.Modules.Zone.ZoneController', Line 450 - function getTouchingZones  -  Studio - ZoneController:450
  17:53:06.946  Script 'ReplicatedStorage.Modules.Zone.ZoneController', Line 327 - function _getZonesAndPlayers  -  Studio - ZoneController:327
  17:53:06.946  Script 'ReplicatedStorage.Modules.Zone', Line 735 - function getPlayers  -  Studio - Zone:735
  17:53:06.947  Script 'ServerScriptService.Script', Line 1016  -  Studio - Script:1016
  17:53:06.947  Script 'ReplicatedStorage.Modules.Zone.Signal', Line 42  -  Studio - Signal:42
  17:53:06.947  Stack End  -  Studio

I’m trying to make entities spawn whenever you’re close to them

This appears to occur when a part is parented to another part which I’d advise against when using ZonePlus due to descendant checks. I’ll resolve the issue in PMs.

Patched an error in v2.1.1 that previously occurred when working with multiple overlapping zones and methods such as getTouchingParts:

Cheers @NotWhutThe for help finding and fixing this.

When I run super quick, it doesn’t work properly. Any suggestions?