I’m making a new game right now where I need different music to be played in different zones, I tried looking for an solution, but I only found solutions where only 1 part was used to play music in zones, but I need my system to be over several parts as the zones are not like squares but are more round (Like i nthe picture below), any Idea how I could script this?
Edit:
Ambience should only be played if the player left the zone, and the ambience shouldnt reset when ever the palyer touches another part in the group
Try using a module or smth like that, bc i don’t know how to do that, maybe region2 may be the solution? (even if i don’t know what that is lol, but it has region on the name) and then i discovered that region2 is outdated and it’s not region2 it’s region3
local zones = workspace:WaitForChild("Zones")
local hits = {}
for i,v in ipairs(zones:GetChildren()) do
v.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if character then
local player = game.Players:GetPlayerFromCharacter(character)
if player and not table.find(hits, player) then
table.insert(hits, player)
print("entered")
end
end
end)
v.TouchEnded:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
if character then
local player = game.Players:GetPlayerFromCharacter(character)
if player and table.find(hits, player) then
table.remove(hits, table.find(hits, player))
print("left")
end
end
end)
end
or
local RunService = game:GetService("RunService")
local zones = workspace:WaitForChild("Zones")
local overlapParams = OverlapParams.new()
overlapParams.FilterDescendantsInstances = {zones}
overlapParams.FilterType = Enum.RaycastFilterType.Exclude
for i,v in ipairs(zones:GetChildren()) do
RunService.Heartbeat:Connect(function()
local parts = workspace:GetPartsInPart(v, overlapParams)
for _, hit in ipairs(parts) do
local character = hit:FindFirstAncestorOfClass("Model")
if character then
local player = game.Players:GetPlayerFromCharacter(character)
if player and not table.find(hits, player) then
table.insert(hits, player)
print("entered")
end
end
end
end)
end
I personally would apply priority for each part, with table.sort you can sort them on priority, ones scanned first will immediately break the iteration on the zone parts and return such parts.
For each kind of part you would need different math. For Cubes I would use X, Y and Z in zone object space, for spheres I’d use the Magnitude and compare it to the sphere radius.
Using .touched like I’ve seen above can be done too, but I wouldn’t do it personally.
You can also make it so if there is no zone detected, it will go to a fallback option OR not change zone.
I’ve been using sound zones for a while now and it is not hard to set up.
If you have lots of zones, I would recommend not scanning each heartbeat, but rather each few heartbeats, 2, 3 or 4, that is more optimised and barely noticable.
Another way to optimise this is by turning all zones into a table with dictionaries in them first, rather than having to read the properties off the parts themselves.
Yet another way to optimise is by making this run using actors, but that requires slightly more insight into how those work, but I am a great fan of “over”-optimising my games.
You can simply add different Parts to different places of your map, make them all invisible and ‘Uncollidable’ and then check if one of the Parts is touched by the player through a Script. (Also make sure that the property CanTouch is enabled)
And make sure that every part covers its place COMPLETELY
If you want to play Music1 when the player touches Part1, you can say
Yeah… But this type isn’t that efficient, and it is not that organized too… Anyways, i think you just need some kind of tags or something like that, idk, but at least, it is something
Yea it’s not very efficient, and can cause bugs, but this is the only way I know to play different sounds in different parts of the map … I’m not that professional either.