Method
Detection¶
ZonePlus splits items into three categories:
- LocalPlayer
- Players
- Parts
These categories then utilise unique methods to determine whether their corresponding item type is within a zone.
Info
It's important to understand that unlike in v1, zones now act as a collective through the ZoneController module. This means information can be generated once in a central area and shared with relavent zones, as apposed to each zone working independently.
LocalPlayer¶
- While a localplayer-connection is active (i.e. when a developer connects to
zone.localPlayerEntered/Exited
)... - Perform a WorldRoot:GetPartBoundsInBox check within the local player. An array of all zone group parts is used as its whitelist.
- Use this result to determine the zones the player is within.
- Update each of these returned zones and determine whether
.localPlayerEntered
or.localPlayerExited
should be fired. - If active, calculate the clock time of the next check based upon the
zone.accuracy
enum.
Players¶
- While a player-connection is active (i.e. when a developer connects to
zone.playerEntered/Exited
)... - Compare the total volume of all zones against the total volume of all player characters (these are pre-determined through events instead of calculating every check).
- If the total characters volume is less than the total zone volume then:
- Iterate through each player in the server.
- Perform a
WorldRoot:GetPartBoundsInBox
check over the local player. A collective of all zone group parts is used as its whitelist. - Find the corresponding zone of these bound parts. If that zone is entirely made up of Blocks, then register instantly.
- If not, then perform a
WorldRoot:GetPartsInPart
check (which is more precise) using the previous result as its whitelist. Register these successful results. - If a returned zone has an active player connection, update it and determine if
.playerEntered(player)
or.playerExited(player)
should be called.
- Else if the total characters volume is greater than the total zone volume then:
- Iterate through each active zone.
- If the zone has an active player connection, perform a
WorldRoot:GetPartBoundsInBox
check of the zones rough area using all character parts within the server as a whitelist. - Using a dictionary, match the bodyparts to their corresponding players.
- For each player detected, perform the same precise checks over their character highlighted in (3).
- Update the zone with these players and fire
.playerEntered(player)
and/or.playerExited(player)
where necessary.
- If active, calculate the clock time of the next check based upon the
zone.accuracy
enum.
Parts¶
- When a part-connection is formed (i.e. when a developer connects to
zone.partEntered/Exited
), apply a touched event to all group-parts within the zone. - When a part touches one of these group-parts, set its
.CanTouch
property tofalse
. - Fire
.partEntered(part)
and form a 'tracking connection' for the part. - While this tracking connection is active...
- Perform a 'tiny check' (of size
(0.1, 0.1, 0.1)
, using the zones group parts as a whitelist) to verify the parts center is still within the zone. - If this returns false, then it means the part is either on the outer bounds of the zone or has exited. Now perform a whole-body
WorldRoot:GetPartBoundsInBox
(orWorldRoot:GetPartsInPart
if more precision if required if the zone contains non-block baseparts) check, with the zones group parts as a whitelist. - If this returns false, then the part has exited the zone. Fire
.partExited(part)
, disconnect the tracking connection and set the parts.CanTouch
property back totrue
. - Else if the tracking connection is still active, calculate the clock time of the next check based upon the
zone.accuracy
enum.
- Perform a 'tiny check' (of size
- If all part-connections are disconnected, disconnect all touched events and end any tracking connections.
Items¶
- Same methodology as
Players
, except using tracked instances fromzone:trackItem(item)
instead of a players character.
Optimisations¶
- Whitelists everywhere. ZonePlus ensures only necessary parts (such as a characters HumanoidRootPart) are tracked and then passed through to whitelists when performing checks.
- A zones Region coordinates are rounded up to the nearest multiple of 4 to ensure it rests on the voxel grid.
- The volume comparisons enable zones to determine players inside with optimal efficiency. For instance, if a server contains a single
8x8x8
zone and 100 players of size4x5x1
, its significantly more efficient to check only the zone (of volume 512), as apposed to every player (of total volume 2000). Likewise, if you have multiple large zones which cover a map and few players in a server, it's going to be significantly more optimal to check each player as apposed to every zone. - For the experimental part events, .Touched abuse checks are enforced to prevent parts firing these events more than the property value of whatever
enum.accuracy
is.