How do I make a simple system where if you are within (for example) 45 studs from a character, the current sound playing in the workspace pauses and another one from the workspace plays, and if you get out of the range (45 studs) the sound that was paused continues. No layers or anything just walk within, current music stops, music plays, walk out, music stops, past music plays.
You could probably just use a script that stores the positions/size (radius) of the sounds and the sound that would be played.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local UPDATE_TIME = 0.25 -- Seconds between updating the sound
local sounds = { -- Store all your sounds here, as many as you want!
{Position = Vector3.new(1, 2, 3), Radius = 5, Sound = <SoundInstance>}
}
player.CharacterAdded:Connect(function(character: Model)
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local position = humanoidRootPart.Position
while humanoidRootPart do -- Loop until the character respawns
for _, soundData in sounds do -- Check all sounds
local sound = soundData.Sound
local soundPos = soundData.Position
local soundRadius = soundData.Radius
local distanceToPlayer = (position - soundPos).Magnitude -- Distance to center of sound
if distanceToPlayer < soundRadius then
if sound:IsPaused() then
sound:Resume() -- The sound is paused so resume it
elseif sound:IsPlaying() == false then
sound:Play() -- The sound hasn't been started yet
end
else
sound:Pause() -- Pause the sound from playing
end
end
task.wait(UPDATE_TIME)
end
end)
Local Script
This script doesn’t stop the sounds when the player leaves the area so the music would continue where it left off but if you don’t want that you can remove the :Resume/:Pause and just use :Stop/:Play
I would store the current playing sound in a variable to avoid playing the same sound multiple times. There’s 2 approaches:
-
Using some kind of RenderStepped function to calculate the distance between the character’s humanoidrootpart and the player’s using Magnitude. Check if you’re playing the correct audio. If you’re not, stop the other one and play the new one.
-
Using a spheric part attached to the humanoidRootPart along with .Touched and .TouchEnded events. Here I would have a table containing parts touching for every player. When the .Touched event fires from a player, add that part to the table and check if it was the first part to be added. If it was, stop the other audio and play the new one. When the .TouchEnded event fires from a player, check if that part was in the table, and if it was, remove it and check if it was the last one remaining. If it was, stop the previous audio and play the new one.
I’ll code the approach #1 since I’d say it’s easier
(LocalScript in StarterCharacterScripts)
local CLOSE_SOUND = game.Workspace:WaitForChild("CloseSound")
local FAR_SOUND = game.Workspace:WaitForChild("FarSound")
local DISTANCE_THRESHOLD = 45
local PART = game.Workspace:WaitForChild("TestingPart") -- You should set this to the character's HumanoidRootPart
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local current_playing_sound
game:GetService("RunService").RenderStepped:Connect(function()
local distance = (PART.Position - hrp.Position).Magnitude
if distance <= DISTANCE_THRESHOLD then
if current_playing_sound ~= CLOSE_SOUND then
FAR_SOUND:Pause()
CLOSE_SOUND:Resume()
current_playing_sound = CLOSE_SOUND
end
else
if current_playing_sound ~= FAR_SOUND then
CLOSE_SOUND:Pause()
FAR_SOUND:Resume()
current_playing_sound = FAR_SOUND
end
end
end)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.