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

Hi, I’m trying to make each Ambient Zone from the playground play a different sound depending on the time of day, but it’s just… not working. No errors in output, and everything is where it should be.

(This is the ambient zone script btw)

-- This creates a zone for every ambient group, then listens for when the local player enters and exits
local LABEL_DURATION = 3
local FADE_INFO = TweenInfo.new(1)
local Zone = require(game:GetService("ReplicatedStorage").Zone)
local localPlayer = game.Players.LocalPlayer
local playerGui = localPlayer:WaitForChild("PlayerGui")
local tweenService = game:GetService("TweenService")
local runService = game:GetService("RunService")
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "AmbientContainer"
screenGui.ResetOnSpawn = false
screenGui.Parent = playerGui

local ambientAreas = workspace.AmbientAreas
for _, container in pairs(ambientAreas:GetChildren()) do

	--
	container:WaitForChild("Part", math.huge)
	--

	local zone = Zone.new(container)
	zone:bindToGroup("EnterOnlyOneZoneAtATime")

	local soundDay = container:FindFirstChild("Day")
	local soundNight = container:FindFirstChild("Night")


--	if soundDay then
		local areaLabel = Instance.new("TextLabel")
		areaLabel.BackgroundTransparency = 1
		areaLabel.Size = UDim2.new(1, 0, 0.08, 0)
		areaLabel.Font = Enum.Font.Garamond
		areaLabel.Text = container.Name
		areaLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
		areaLabel.TextTransparency = 1
		areaLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
		areaLabel.TextStrokeTransparency = 1
		areaLabel.TextScaled = true
		areaLabel.TextWrapped = true
		areaLabel.Name = container.Name
		areaLabel.Parent = screenGui

		local endLabel = Instance.new("BindableEvent")
		--			soundDay.Name = container.Name
		--			soundDay.Parent = screenGui

		zone.localPlayerEntered:Connect(function()
			
			while true do
				wait(0.1)
				if game.Lighting.ClockTime >= 7 and game.Lighting.ClockTime <= 20 and soundDay.IsPlaying == false and soundNight.IsPlaying == true then
					soundNight:Stop()
					soundDay:Play()
				elseif game.Lighting.ClockTime >= 21 and game.Lighting.ClockTime <= 6 and soundDay.IsPlaying == true and soundNight.IsPlaying == false then
					soundNight:Play()
					soundDay:Stop()
				end
			end
			
			--				tweenService:Create(soundDay, FADE_INFO, {Volume = originalVolume}):Play()
			tweenService:Create(areaLabel, FADE_INFO, {TextTransparency = 0, TextStrokeTransparency = 0.3}):Play()
			local ended = false
			task.spawn(function()
				local endTick = tick() + LABEL_DURATION
				repeat runService.Heartbeat:Wait() until tick() >= endTick or ended
				if not ended then
					endLabel:Fire()
				end
			end)
			endLabel.Event:Wait()
			ended = true
			tweenService:Create(areaLabel, FADE_INFO, {TextTransparency = 1, TextStrokeTransparency = 1}):Play()


			zone.localPlayerExited:Connect(function()
				--				local fade = tweenService:Create(soundDay, FADE_INFO, {Volume = 0})
				--				fade:Play()
				endLabel:Fire()
				--				fade.Completed:Wait()
				--				fade:Destroy()
			end)
		end)
	end
--end

Idk what i’m doing wrong

Where is this script located at?
And you have a while true do loop running when it doesn’t need one, and it’s also blocking the rest of the code block from running.

It’s the default Ambient Zone script, it’s at StarterPlayerScripts

Hello, this looks really cool!
Is there a way to see if a part is fully inside a zone, not partly.
Thanks

Hey mate I think I found a bug. I was trying to use this module for a door system, where if you’re nearby you can click E to open it. The module worked great when I ran zone:playerAdded(); zone:playerExited(), however it didn’t work as well with zone:getPlayers(). Im not sure what the error could be, as I havent looked over the source code, however if it helps, I fired a part from the server, to the client (for a ui), then back over to the server where the script is located. I tried this without firing the part to clients and servers, by directly indexing it, and the same issue occured. In the script that is fired to last, the one that handles the door opening, I first get the part, then create a new zone using zone.new(), then finally run zone:getPlayers. My character was clearly inside of the part, however the table returned {} instead of {game.Players.MemezyDev}. Im not sure what the issue was since half the times it worked, other times it didnt. Maybe you could look over the code and see what the issue was for anybody in the future?

Not currently I’m afraid due to the way spatial queries work. That could make a good roblox feature request, for instance WorldRoot:GetPartsFullyInPart(PartInstance part, OverlapParams overlapParams)

It’s worth noting playerAdded and playerExited are events which you connect to instead of calling, e.g. zone.playerAdded:Connect(func). It’d be best to share a link to an uncopylocked place if you’re still having troubles.

4 Likes

If you want me to I could, however I used an alternate method of this that worked, so I would need to remember the exact code I wrote down, pretty sure I forgot what I wrote at the time of making my comment

1 Like

Just implemented this into my new game, its absolutely amazing and makes things so much easier. Very simple to use and implement 10/10

2 Likes

I’m having an issue where the playerExited event randomly doesn’t fire for a zone, and subsequently, none of the entered/exited events fire for any of the zones. It’s so strange because it doesn’t happen consistently with any one action or zone. It just randomly seems to happen and I have no idea how to fix it lol.

This module fails to work when you are using 2 partEntered or partExited events if both models which are bound to those events have the same parent.

Show code.

Also show code.

More than likely you’re both using this module wrong as I’ve had no issues with either given events.

1 Like

Hi, I am making a safe zone script for a specific team, with ZonePlus, but it doesn’t seem to work. I followed the documentation and tried the scripts in the playground but it doesn’t work

local Target = game:GetService("Workspace"):WaitForChild("Pitch"):WaitForChild("GK")["Space"]
local Zone = require(game:GetService("ServerScriptService"):WaitForChild("Modules")["Zone"])

local Parts = {

	Home = Target:FindFirstChild("Home"),
	Away = Target:FindFirstChild("Away"),
}

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Teams = game:GetService("Teams")
local Players = game:GetService("Players")
local ValuesFolder = ReplicatedStorage:WaitForChild("Values")
local Space = ValuesFolder:WaitForChild("Space")

local SpaceValues = {

	Home = Space:FindFirstChild("Home"),
	Away = Space:FindFirstChild("Away"),
}

local Vector = Vector3.new(167.28, 1.121, -1.362)
local Vector1 = Vector3.new(-161.846, 1.121, -1.362)


local HomeZone = Zone.new(Parts.Home)
local AwayZone = Zone.new(Parts.Away)

HomeZone.playerEntered:Connect(function(player)
	if SpaceValues.Home.Value == true then
		if player.Team == Teams["-Home GK"] then return end
		player.Character:MoveTo(Vector)
	end
end)

AwayZone.playerEntered:Connect(function(player)
	if SpaceValues.Away.Value == true then
		if player.Team == Teams["-Away GK"] then return end
		player.Character:MoveTo(Vector1)
	end
end)

By the way, the Parts are parentered inside a folder, one folder for home and another for away.

image

Have you tried doing a print/warn inside the playerEntered…? Also, is your value actually true?

I set it to true in another server script, and yes I have tried prints and it doesn’t seem to print

So in this case, it wouldn’t print true?

No, I’ve tried multiple things and it still doesn’t print.

Are you able to make a place repo…? I don’t see how your code isn’t working.

I can’t right now, but even using the example scripts in the post doesn’t work for me.

The examples work, it’s fairly obvious you’re missing or doing something wrong which is why a repo is needed.

I found the issue, nothing wrong with the script, I made the part a bit bigger and it worked somehow, maybe it wasn’t detecting the player before idk