Introduction
Summary¶
ZonePlus is a module enabling the construction of dynamic zones. These zones utilise the new Spacial Query API and BasePart.CanTouch property to effectively determine players and parts within their boundaries.
Creating a zone is as simple as:
-- Assuming we place ZonePlus in ReplicatedStorage
local Zone = require(game:GetService("ReplicatedStorage").Zone)
local container = workspace.SafeZoneContainer
local zone = Zone.new(container)
Zones take one argument: a container. A container can be any non-basepart instance (such as a Model, Folder, etc) that contain descendant baseparts. Alternatively a container can be a singular basepart instance, or a table containing an array of baseparts.
Info
Zones are compatible with all basepart classes however it's recommended to use solely Blocks (i.e. Parts with Shape 'Block') when possible as these are better optimised (since only WorldRoot:GetPartBoundsInBox
needs to be called instead of WorldRoot:GetPartsInPart
).
These group parts are then used to define the region and precise bounds of the zone.
Info
Zones are dynamic. This means if a group part changes size or position, or if a basepart is added to or removed from the zone group, then an internal _update()
method will be called to recalculate its bounds.
Once constructed, you can utilise zone events to determine players, parts and the localplayer entering or exiting a zone. For instance, to listen for a player entering and exiting a zone, do:
zone.playerEntered:Connect(function(player)
print(("%s entered the zone!"):format(player.Name))
end)
zone.playerExited:Connect(function(player)
print(("%s exited the zone!"):format(player.Name))
end)
Info
On the client you may only wish to listen for the LocalPlayer (such as for an ambient system). To achieve this you would alternatively use the .localPlayer
events.
Important
Initially zone parts should be located within Workspace to function properly. If you wish to move zones outside of Workspace (e.g. to prevent them interacting with other parts), consider using zone:relocate().
Important
Zone parts must belong to the 'Default' (0) collision group.
If you don't intend to frequently check for items entering and exiting a zone, you can utilise zone methods:
local playersArray = zone:getPlayers()
Discover the full set of methods, events and properties at the Zone API.
Optimisations¶
Zones by default perform up to 10 checks per second in the centre of characters. This behaviour can be changed by modifying the Accuracy and Detection of zones:
Accuracy¶
This determines the frequency of checks per second.
The accuracy of a zone can be changed two ways with a corresponding Accuracy Enum:
-
Using the
zone:setAccuracy(itemName)
method:zone:setAccuracy("High")
-
Setting the
zone.accuracy
property:zone.accuracy = Zone.enum.Accuracy.High
By default accuracy is High
.
Info
Modifying the accuracy of one zone may impact the accuracy of another due to the modules collaborative nature.
Detection¶
This determines the precision of checks.
The way a zone detects players and parts can be changed two ways with a corresponding Detection Enum:
-
Using the
zone:setDetection(itemName)
method:zone:setDetection("WholeBody")
-
Setting the
zone.enterDetection
andzone.exitDetection
properties:zone.enterDetection = Zone.enum.Detection.WholeBody zone.exitDetection = Zone.enum.Detection.WholeBody
By default enterDetection and exitDetection are Centre
.
Info
Modifying the detection of one zone may impact the detection of another due to the modules collaborative nature.
Warning
Setting enterDetection
to (Zone.enum.Detection.WholeBody
or Zone.enum.Detection.Automatic
) and exitDetection
to Zone.enum.Detection.Centre
may cause the entered and exit events to trigger rapidly when the player lies on the bounds of the zone.