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

Coming as a mega update tomorrow/friday :+1:

2 Likes

Can I have a question on how much this would affect existing code (performance wise)? I’ve seen those benchmarks from OverHash and it seems pretty slower than now deprecated Region3 methods.

ZonePlus is currently built off EgoMoose’s RotatedRegion3 (that extends upon Region3s) which is essentially what the new API handles internally. You can be confident on Roblox supporting and improving Spatial Queries going forwards whilst this isn’t a guarantee for deprecated ones like the Region3 methods.

5 Likes

Because parts have 2048 studs size limit and I need to check even larger are than that may I ask if is there going to be an option (or is there already?) to create Zone without physical object (with CFrames and such)?

1 Like

Last question, does ZonePlus still detect players if its in localscript?

v3.0.0 Breakdown

New version, yay!

1. Goodbye RotatedRegion3, hello OverlapParams

Internal Region and RotatedRegion3 checks have been entirely replaced with the new Spatial Query API. This should bring about performance gains, particularly over the long term as this API is improved.


2. You can now track anything

With new Item events and methods you can now track anything. Humanoid Dummies? Check. Zombie NPCs? Check. Spaceships? Check. Pineapple Bombs? Check.

First, setup your events:

zone.itemEntered:Connect(function(item)
    print(("item '%s' entered the zone!"):format(item.Name))
end)

zone.itemExited:Connect(function(item)
    print(("item '%s' exited the zone!"):format(item.Name))
end)

Then simply track any BasePart, Character or NPC you wish to have detected when entering and exiting the zones:

zone:track(zombieNPC)
zone:track(spaceshipHullPart)
etc

@g_dson @Stellabotrus This solves the humanoidEvent feature request and touchTransmitter issue you mentioned.


3. One-time use methods

Introducing zone:onItemEnter and zone:onItemExit which track a specific item until it has entered/exited the zone, then calls the given callbackFunction.

local item = character:FindFirstChild("HumanoidRootPart")
zone:onItemEnter(item, function()
    print("The item has entered the zone!"))
end)
local item = character:FindFirstChild("HumanoidRootPart")
    zone:onItemExit(item, function()
    print("The item has exited the zone!"))
end)

This is useful for scenarios where you may only want to listen for an item entering/exiting a zone after a certain trigger, instead of constantly.


4. Enhance zones with bindable SettingsGroups

A frequently reported difficulty in the past has been to do with zones that rest directly next to each other. If you were creating zones for example which played and stopped music, you would often find music played/stopped incorrectly as the entered event of one zone would fire before the exited event of the other zone.

This can now be overcome by simply binding those zones to the same settingsGroup:

for i = 1, 3 do
    local zone = Zone.new(part)
    zone:bindToGroup("EnterOnlyOneZoneAtATime")
end

settingsGroups currently only contain one property, onlyEnterOnceExitedAll (which defaults to true), although can be customised in the future with ZoneController.setGroup.

Behaviour without SettingsGroups:

Behaviour with SettingsGroups:

@LordMerc @Maxx_J This helps overcome the problems you both mentioned a few months back. I’ve updated the playground examples to now include this.


5. It’s time to disappear…

You can now snap zones out of workspace with the new relocate method:

zone:relocate()

Perfectly balanced, as all things should be.

This is also accompanied with a new constructor, Zone.fromRegion, enabling the construction of zones without any containers/baseparts:

local zoneCFrame = CFrame.new()
local zoneSize = Vector3.new(3000, 3000, 3000)
local zone = Zone.fromRegion(zoneCFrame, zoneSize)

6. Additional

  • By default, Zones will now only check the Centre of characters (i.e. their HumanoidRootParts). This is because it provides performance gains and most users previously didn’t require whole-body checking. If you wish to revert back to the whole-body checking of characters, simply do:
    zone:setDetection("WholeBody")
    
  • Replaced Maid with Janitor by @pobammer
  • Replaced Signal with GoodSignal by @stravant

A full breakdown of API changes can be found here:

31 Likes

Awesome update!
Found an unsual bug (which may or may not be roblox’s own), but it’s with the paint zone.
Video kinda speaks for itself on the issue.

2 Likes

My bad, looks like I forgot to update the paint zone at the playground! Thanks for the find, should be updated now:

2 Likes

May I ask if there is any improvements with zones that contains more parts? Last time I tried it, it performed really wonky.

Thanks for the amazing update keep it up Forever!

I made a slight fix to one of the whitelists for v3 although unless you’re making your zones out of hundreds of complex shapes there should be negligible difference to performance.

Can you expand on what you mean by wonky, and/or provide a way to reproduce the behaviour?

I am creating mining game and I am using zone to tag player if they’re in mine in order to calculate the depth that they’re currently on.

Video of the behavior:
Cloudfire Studio Project #3 - Roblox Studio (gyazo.com)

But as I just realized the problem is in the complex shapes, is there any chance to make something like “BoundingBox method” of all descendants, so it will ignore missing parts and just perform as a regular cube?

Is there any way to set a character as a zone and use it as a hitbox? If so, what would be the best method of doing that?

Currently using raycasting for character hitboxes and I’m not too happy with it. I need to detect when characters collide with each other.

There is an error on hrp.Size in ZoneContriller due to hrp is nil. Changing FindFirstChild(“HumanoidRootPart”) to WaitForChild silenced this error

These are all now possible with zone:relocate() and Zone.fromRegion(cframe, size) the latest v3 release!

More details and videos here:

3 Likes

Instead of creating multiple zones with lots of complex parts, consider making a single zone instead with one gigantic part which engulfs the whole mine (or even utilise the new Zone.fromRegion(cframe, size) constructor). This will be significantly more performant.

Thanks for the report, this has also been fixed in the latest release:

Well this isn’t possible but as I am now seeing Zone.fromRegion is definitely the way to go thank you so much!

1 Like

Not for ZonePlus as zones are primarily designed to be static (although we do support dynamically moving objects). It may be worth exploring other resources like Raycast Hitbox instead:

Thanks for the update!
However, an issue occurred in my codebase that was previously working fine:


‘LightningServer’ is a script that gets a random point from a zone every few seconds. The error occurs when calling :getRandomPoint() on the zone as you can see from the error log.

Edit: It seems zone.playerEntered and zone.playerExited don’t fire anymore? I’m probably missing something though… Using the latest push from GitHub.

Hello friend, I found a very serious problem. When the character keeps moving in the Zone, the memory (physics / steps) of the server leaks seriously! I don’t know if you noticed,,,