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

ZonePlus v3

:floppy_disk: Source Code | :open_book: Documentation | :ocean: Playground

ZonePlus utilises the new Spatial Query API and Whitelists to effectively determine players, parts and custom items within a zone. You can have as many zones as you like, as large as you like, with zero-to-minimal additional cost to performance.

For those looking to benefit from v3 you can find a detailed breakdown here.

https://www.roblox.com/library/6245329519/ZonePlus

-- This constructs a zone based upon a group of parts in Workspace and listens for when a player enters and exits this group
-- There are also the ``zone.localPlayerEntered`` and ``zone.localPlayerExited`` events for when you wish to listen to only the local player on the client
local container = workspace.AModelOfPartsRepresentingTheZone
local zone = Zone.new(container)

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)
-- This constructs a zone based upon a region, tracks a Zombie NPC, then listens for when the item (aka the Zombie) enters and exits the zone.
local zoneCFrame = CFrame.new()
local zoneSize = Vector3.new(100, 100, 100)
local zone = Zone.fromRegion(zoneCFrame, zoneSize)

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

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

zone:trackItem(workspace.ZombieNPC)
-- This is a one-time use method which calls the given function when the given item enters the zone
local item = character:FindFirstChild("HumanoidRootPart")
zone:onItemEnter(item, function()
    print("The item has entered the zone!"))
end)

:sparkles: What’s new


:clapper: Get Started


:package: Installation


:bulb: API


:rocket: Examples

Safe Zone

Paint Zone

Coin Spawner

ZUS5xhQ

Voting Pads

WIslioQ

Random Part Generator

f4be5f98a1f9e52e747dbd994b471c98

Ambient Areas

NPC Damager

Sliding Doors


Credit

Big thanks to these people for their resources and contributions:

ZonePlus is completely free and open source. It operates under an MIT License; you only have to provide credit and link back to this thread to use and modify. It’s taken a considerable amount of time to develop so any feedback is greatly appreciated!

395 Likes
Help with brainstorming a script
How would I check if something is consistently touching something?
Zone+ v1 (deprecated) | Retrieving players within an area/zone
Project: Hood - The Crew Clashes Update
Region3 doesn't work
GUI meant for client shows for all players
Optimizing region code running on Heartbeat
How do I count all the players inside a part?
TouchEnded fires whenever player is inside of the BasePart
How can I fix this damage zone?
TTD 3 | Game Credits
How would I check if something is consistently touching something?
New Part Collision Property: CanTouch [ACTIVATED]
Is it possible for an event to fire when I player enters and leaves a certain region (maybe using region3)?
Help with region3
How do I add a Cooldown in my script to prevent overlapping?
Trying to create a Safe zone
Invisible part that changes atmosphere density only while touched
Kill all players in a certain area
Fakejeffret Games game Credits
Tool constantly cloning to character and destroying
What should I do to recognize the person in the car or motorcycle when touched?
Safezone (No tools in certain area & receive out of that area)
How to make a sword fighting area?
Forcefield gets removed every time I shoot at somnebody in the safezone
Reliable Way to detect when a Player enters a Zone?
Check if 2 parts intersect
How would I make a safe zone that wouldn't make you gain any leaderstats?
Region3 Support
Detecting Player In a Certain Area Question
Kit Hub | "The Better ROBLOX Toolbox"
How Would I Make My Coin Script Spawn Random Coins Within A certain Radius?
How could I possibly get this to work? (Player)
How do I make this not look bad?
How to seperate a map into different regions/districts, so I can detect what region of a map a player is in?
How do I make this?
Detecting where a part hits another part
Detect when a player is in or not in a part
Help detect in players in-game region position
PvP Zone not working
Changing Coin UI to fit area player is in
Detect when a player is in or not in a part
Anti Fly (server side)
How to make irregularly-shaped region detection?
Stat Boost Script Not Working
Which method would be most reliable for Touched?
Which method would be most reliable for Touched?
Music Regions Are Lagging My Game
Needing help with region3s playing sounds
I want to detect when the player is inside of a specific part
How to make a selected group of players teleport to a different game
Zone API v1.0 is out!
Is it really possible to build a true open world game (no loading screens between areas) on Roblox?
Coroutine vs While True loop or other ideas for a script that runs on proximity
RoPlay - Update Log & Attributions
Effecient Alternative to TouchEnded()?
Problem with Finding Parts within a Region3
How do you play a sound for the player if they join a team?
Game stops awarding me points at 4 Points thinking that I left the zone even tho I am still in it
What’s the best way to make an environmental changer?
Biome Detection System
Checking instances inside Region3
How would I make a maze character
Region3 not responsive
How do you make a player die after time runs out?
RPG NPC breaks if there is more than 1
TouchEnded Issue
"Wait until" code stops entire script
Help making a checkpoint system
Welcome to 1867 Historical Role Play

Really nice work you’ve done
Keep it up :+1:

10 Likes

This is awesome! I will definitely be using this for my games. Thanks!

9 Likes

Great to see performance optimizations and new features, will definetely updating v1 to v2. Thanks for releasing this!

5 Likes

Fantasic! I am definitly using this to create dynamic lighting zones such as when entering a desert zone or a cave!

Thanks again @ForeverHD

7 Likes

I was definitely pondering about subdividing a world into “zones”, where each zone would have its own environment effects and contextual information, such as a spooky forest with a boss fight.

This resource you shared suggests to me that design is not a bad idea.

7 Likes

I’m pretty new to scripting lua
So I need a bit of help w/ my script if u don’t mind
Basically I want to player to be given a tool once entered. And the tool destroyed once they leave the zone

local Zone = require(game:GetService("ReplicatedStorage").Zone)
local group = workspace.areanas._1.swordzone
local zone = Zone.new(group)
local Players = game:GetService("Players")

local Sword = game.ServerStorage.ClassicSword
local char = Players.Character

zone.partEntered:Connect(function(plr)
	for _,v in pairs(char.Character:GetChildren()) do
		if v.Name == Sword.Name then
			return
		end
	end    
	for _,v in pairs(char.Backpack:GetChildren()) do
		if v.Name == Sword.Name then
			return
		end
	end
	Sword:Clone().Parent = plr.Character
end)

zone.playerExited:Connect(function(plr)
	if not char then return end
	for _,v in pairs(char:GetChildren()) do
		if v.Name == Sword.Name then
			v:Destroy()
		end
	end
	for _,v in pairs(char.Backpack:GetChildren()) do
		if v.Name == Sword.Name then
			v:Destroy()
		end
	end
end)

Character is not a valid member of Players "Players"
Script 'ServerScriptService.Script', Line 7 - local char = Players.Character

I copied and pasted parts of my old zone script a friend of mine made for me so idk if it will still work

2 Likes

Great work! Can i use in my game?

3 Likes

For zonePlus specifically there’s one bug I can see at a glance:

For this scenario you’ll want to use zone.playerEntered instead of partEntered.

For the entire script itself, your code breaks as you’re trying to reference Character for the PlayerService (whereas you can only do this on a player instance), try something like this instead:

local Zone = require(game:GetService("ReplicatedStorage").Zone)
local group = workspace.areanas._1.swordzone
local zone = Zone.new(group)
local swordName = "ClassicSword"
local sword = game:GetService("ServerStorage")[swordName]

zone.playerEntered:Connect(function(plr)
	local char = plr.Character
	local foundSword = char:FindFirstChild(swordName) or plr.Backpack:FindFirstChild(swordName)
	if not foundSword then
		sword:Clone().Parent = plr.Character
	end
end)

zone.playerExited:Connect(function(plr)
	local char = plr.Character
	local foundSword = char:FindFirstChild(swordName) or plr.Backpack:FindFirstChild(swordName)
	if foundSword then
		foundSword:Destroy()
	end
end)
2 Likes

Sure you’re free to use and modify the project in anyway you like - simply provide credit and link back to this thread where possible!

4 Likes

I will show updates from devforum. I can add your credit to my devforum post when game release.

3 Likes

Excellent Work! I am using this awesome module to make a checkpoint system. I have a question! There is any method you already made that can return which “part” player entered?

Like I have few checkpoint C1, C2, C3 etc… in the same folder.
If player entered C3 without entered C2 before. Player checkpoint should still C1. So I think I need to check which “part” player exactly entered.

There is my code I already write I think this would work too.

local checkPointGroup = game.Workspace.Map1.Zones.CheckpointZone:GetChildren()
for _, checkPoint in ipairs(checkPointGroup) do
	local checkpointZone = Zone.new(checkPoint)
	checkpointZone.playerEntered:Connect(function(player)
		print(player.Name .. " Entered " .. checkPoint.Name)
	end)
	
	checkpointZone.playerExited:Connect(function(player)
		print(player.Name .. " Exited " .. checkPoint.Name)
	end)
end

But just wondering is there is a method or other way can return which “part” player entered? Thank you for this awesome module!

2 Likes

When the player enters, you could iterate through it’s character parts and call zone:findPart(basePart) to determine which of its parts are within the zone.

Alternatively you could use the partEntered and partExited events when BasePart.CanTouch goes live.


@Maurity_Dev Sure that’s perfectly fine

2 Likes

No clue why but Zone+ V2 doesnt even work for me, I’ve tried to do a safezone, tampered with it, then went to your original script and used it but it still didn’t work. It could be because I put the spawn into the safezone?

2 Likes

Great job with the update and optimizations :+1:

Just updated and logged it into my patch notes for my game’s next major update.

4 Likes

v2 isn’t backwards compatible with v1 (due to the new optimisations which require a different API) therefore if you’re using code from v1 this is likely why.

It’s also important to note that the additionalHeight parameter has been removed, therefore the group-parts that make up the zone have to encapsulate the entire area of the zone.

You can view coded examples for v2 at the new playground, including a safe zone example, and for more information you can visit the docs.

1 Like

I have V2 but I didn’t remember to remove additionalHeight, thank you so much for getting a quick response. Honestly, I enjoy zone+ V2, good job making it.

2 Likes

Hello, just want to let you know that the link for the API takes you to “https://1foreverhd.github.io/ZonePlus/zone/”, which is an Error 404, instead of “Zone - ZonePlus”.

2 Likes

Quick question;

Whenever I click play, both in Studio and in real servers, the descendant BaseParts of my ZoneGroup get destroyed. Do you know of a solution to this issue?
There are no other scripts in the game at all, and it’s currently just meshes and baseparts in the game.

My script is as follows:

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

zone.localPlayerEntered:Connect(function()
	PlayThing()
end)

The ZoneGroup is as follows:
75fc3e91dc343a30957775c8687cb040

1 Like

ZonePlus shouldn’t be destroying any descendant baseparts. Can you provide a video showing the workspace before and after, or DM me a stripped-down place file with the zone where parts are being destroyed.

1 Like