Region3 not responsive

  1. What do you want to achieve?
    Music playing and text popping up depending on which region you’re in. Kinda like Mafia 1 and GTA:SA.

  2. What is the issue?
    There’s a really strange thing going on where sometimes it takes time for the music to play and the text pop up, and sometimes, the music takes time to stop playing.

I followed AlvinBlox’s tutorial on how to make music play when you’re in that region, but I sorta modified it to tween the text and music to make it more like an open-world game.

  1. What solutions have you tried so far?
    • I tried googling the problem, nothing relevant showed up
    • I read my code thrice
    • I got rid of the tweens, but it didn’t make a difference
    • I read an article about Region3 in the developer hub, didn’t understand a single thing
    • I changed the while wait() loop time, still didn’t make a difference

I am really new to Region3, so I don’t really know what I’m doing here

here’s the entire code block:

local regionsWP = game.Workspace:WaitForChild("Regions")
local TS = game:GetService("TweenService")

local soundFadeTime = 1
local uiFadeTime = 2

local soundInfo = TweenInfo.new(soundFadeTime,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,0,false) 
local uiInfo = TweenInfo.new(uiFadeTime,Enum.EasingStyle.Quart,Enum.EasingDirection.Out,0,false)

local found = false

local soundOn = {Volume = 1.5}
local soundOff = {Volume = 0}

local uiOn = {TextTransparency = 0, TextStrokeTransparency = 0}
local uiOff = {TextTransparency = 1, TextStrokeTransparency = 1}

local uON = TS:Create(script.Parent.RegionText, uiInfo, uiOn)
local uOFF = TS:Create(script.Parent.RegionText, uiInfo, uiOff)

while wait(2) do
	for i, v in pairs(regionsWP:GetChildren()) do
		found = false
		local region = Region3.new(v.Position - (v.Size/2), v.Position + (v.Size/2))
		
		local sON = TS:Create(script.Parent.SoundRegions[v.Name],  soundInfo, soundOn)
		local sOFF = TS:Create(script.Parent.SoundRegions[v.Name],  soundInfo, soundOff)
		
		local parts = game.Workspace:FindPartsInRegion3WithWhiteList(region, game.Players.LocalPlayer.Character:GetDescendants())
		for _, part in pairs(parts) do
			if part:FindFirstAncestor(game.Players.LocalPlayer.Name) then
				found = true
				break
			else
				found = false
			end 
		end
		if found == true then
			script.Parent.RegionText.Text = v.Name
			if script.Parent.SoundRegions[v.Name].IsPlaying == false then
				if script.Parent.SoundRegions[v.Name].Volume == 0 then
					sON:Play()
					uON:Play()
					script.Parent.SoundRegions[v.Name]:Play()	
				end
				break
			end
		else
			uOFF:Play()
			sOFF:Play()
			sOFF.Completed:Wait()
			script.Parent.SoundRegions[v.Name]:Stop()
		end
	end
end

Yep that right there is the problem, a yield

When it happens it will stop the detection and cause issues. Use task.spawn or coroutine.wrap to avoid this.

Also why not use zone plus?

2 Likes

Thank you for the swift response.
While I was doing my research about detecting that a tween has completed it’s task, I also stumbled upon a reply telling me to use task.spawn or coroutine.wrap, but I can’t figure out how to use them.

Also, what’s zone plus?

The issue is you don’t want the while loop to wait for this tween. If the while loop has to wait for this one tween it will stop detecting and hence not be responsive.

The solution is to create a “new script” or properly named thread that will do the waiting in the background. To do this you can use task.spawn or coroutine .wrap like so:

task.spawn(function()
			sOFF.Completed:Wait()
			script.Parent.SoundRegions[v.Name]:Stop()
end)
--coroutine
coroutine.wrap(function()
			sOFF.Completed:Wait()
			script.Parent.SoundRegions[v.Name]:Stop()
end)()--create coroutine function then execute it

A solution to zone detection which is more efficient as it only detects players and the hrp, instead of all the parts inside the zone.

1 Like

Seems like ZonePlus is the way to go when it comes to these things, thank you so much for introducing it to me!