Zone+ is a lightweight application that utilises regions and raycasting to efficiently determine players within an area.
What’s the best method of retrieving players within an area/zone on the server?
"Using touched/untouched events!" - This was actually how I handled zone checking when I first began developing. Not only do these work incorrectly (untouched often fires before touched, untouched sometimes never fires at all when leaving a part, etc) but they can cause lag when complex shapes enter them.
"GetTouchingParts!" - The one major flaw with this function is it doesn’t work with uncancollided parts. If the player jumps off the part, they won’t be registered. buildthomas and evaera have created a solution for this if you’re interesting in exploring this path.
"Magnitude checks!" - Sorry circle worshippers, but the square lovers are going to have something to say here.
"Region3" (by itself) - Polgons hate him. Scientists at Cambridge university have found out… no.
"Raycasting" (by itself) - Fire ray below player’s character, check if part below, bam! Polygons and circles are happy bunnies now. Shame the server isn’t. This method is fine for small servers, but fails to scale effectively for servers with increasingly larger amounts of players with recursive checks.
The holy grail
Region3 + Raycasting
Setup a group of parts to represent your zone
Calculate the maximum and minimum boundaries of this zone
Create a Region3 value using these bounds
Get players in this region using FindPartsInRegion3. This function returns a list of parts, which you can use to check for a player’s character.
For the players returned in the region check, fire a ray below from the HumanoidRootPart (not too far as this causes lag). If one of the zone’s parts is returned, we can safely say the player is within that zone.
No need to unnecessarily check every player within the server. Simply calculate a ‘rough’ area and determine who’s in the exact zone for players within that region.
Region3 and raycasting are ‘light-weight’. You can run these multiple times a second with minimal effect to performance.
Example 1 - Retrieving Players
local ZonePlus = require(4664437268) -- Initiate Zone+ local ZoneService = require(ZonePlus.ZoneService) -- Retrieve and require ZoneService local group = workspace.YourGroupHere -- A container (i.e. Model or Folder) of parts that represent the zone local zone = ZoneService:createZone("ZoneName", group, 15) -- Construct a zone called 'ZoneName' using 'group' and with an extended height of 15 local playersInZone = zone:getPlayers() -- Retrieves an array of players within the zone
Example 2 - Entering/Exiting Events
local ZonePlus = require(4664437268) local ZoneService = require(ZonePlus.ZoneService) local group = workspace.YourGroupHere local zone = ZoneService:createZone("ZoneName", group, 15) zone.playerAdded:Connect(function(player) print(player.Name,"entered the zone!") end) zone.playerRemoving:Connect(function(player) print(player.Name,"exited the zone!") end) zone:initLoop()
For coded examples, visit the Zone+ Playground.
Safe Zone (using additionalHeight, a loop and 2000 randomly generated parts)
Safe Zone (using uncancollided parts and zone events)
Zone+ is actively maintained by the HD Admin Team; feel free to report bugs, suggest features and make pull requests at our repository.
Special thanks to: