ZonePlus v2 | Construct dynamic zones and effectively determine players and parts within their boundaries

ZonePlus

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

Construct dynamic zones and effectively determine players and parts within their boundaries.


:rocket: Examples

Safe Zone

Paint Zone

Coin Spawner

ZUS5xhQ

Voting Pads

WIslioQ

Random Part Generator

Ambient Areas


:sparkles: What’s new


:clapper: Get Started


:package: Installation


:bulb: API


Additional

  • We highly recommend users of v1 transition to v2 due to its significant optimisations and greater ease of use. v2 is not backwards compatible with v1.

  • There is no additionalHeight parameter with v2 (for optimisations) so ensure your zone parts encapsulate the entire zone, as apposed to being flat parts.

  • 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.

  • This project has taken a considerable amount of time to develop so any feedback is greatly appreciated!

212 Likes

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

5 Likes

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

6 Likes

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

4 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

6 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.

6 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

1 Like

Great work! Can i use in my game?

2 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)
1 Like

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!

1 Like

i can credit but not from game description is it ok?

2 Likes

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

2 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!

1 Like

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

1 Like

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?

1 Like

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