Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

[SOLVED] How would I make an audio play in a different area?

Asked by 4 years ago
Edited 4 years ago

Introduction

I want to create an immersive roleplay game, but I wish to make an area play a specific audio. For example, the player enters the wilderness, and I want it to play music that is related to that.

As for my attempts, I made two parts; InsidePart and OutsidePart. InsidePart lets the script know that the player has entered the inside of the area. OutsidePart will let the script know if the player has exited the area.

Scripts

My script inside InsidePart:

script.Parent.Touched:Connect(function(hit)
    if hit.Parent:FindFirstChild('Humanoid') then
        workspace.InsideAudio:Play()
        workspace.OutsideAudio:Stop()
    end
end)

My script inside OutsidePart:

script.Parent.Touched:Connect(function(hit)
    if hit.Parent:FindFirstChild('Humanoid') then
        workspace.InsideAudio:Stop()
        workspace.OutsideAudio:Play()
    end
end)

Conclusion

Any help please? It doesn't work when it's supposed to.

P.S, I heard that placing audio inside of the workspace will play it server-wide, placing audio inside of StarterPlayer will play it client-side. Let me know if you know how to make it play client-side only. Thanks!

0
you could place an invisible part to play the audio and give a specific range in which the audio plays by editing its properties. Roviospace 22 — 4y
0
Alright, I'll try that later. But what I want is when a player enters the part, it will play the audio. Thanks for the suggestion anyways. Sensei_Developer 298 — 4y

1 answer

Log in to vote
0
Answered by 4 years ago
Edited 4 years ago

I think you'd be better off using Region3 for this kind of thing. I'll give you some example code and explain every line in detail, as well link some sources.

-- put this in a local script
local Players = game:GetService("Players") -- We get the Players Service in order to get LocalPlayer, and using GetPlayerFromCharacter method.
local RunService = game:GetService("RunService") -- We will be using RunService.Heartbeat 
--  event to check whether or not our player is in the area

local Client = Players.LocalPlayer -- I prefer to call LocalPlayer client; 
-- it's just my personal preference.
local InsideAudio = workspace.InsideAudio -- or path to the audio
local OutsideAudio = workspace.OutsideAudio -- or path to the audio


local InsidePart = workspace.InsidePart -- or path to the part
local OutsidePart = workspace.OutsidePart -- or path to the part

function CreateRegion3FromPart(Part)
    local PartSizeDivided = Part.Size / 2 -- Divides the Part Size in two
    return Region3.new(Part.Position - PartSizeDivided, Part.Position + PartSizeDivided)
end
--CreateRegion3FromPart creates a Region3 by getting the bottom low corner and top corner
-- via subtracting and adding to Part.Position

local InsideArea = CreateRegion3FromPart(InsidePart) -- Creates the Region3 Area
local OutsideArea = CreateRegion3FromPart(OutsidePart) -- Creates the Region3 Area

local Connection -- Connection variable, this is where the connection will be stored

-- This function itself checks whether or not the player is in the Area, and then plays the sound
function Check()
    -- workspace:FindPartsInRegion3() gets the parts in Region3's.
    local PartsInside = workspace:FindPartsInRegion3(InsideArea, nil, math.huge)
    local PartsOutside = workspace:FindPartsInRegion3(OutsideArea, nil, math.huge)

    -- These variables exist to check if the player is inside or outside
    local PlayerInside = false
    local PlayerOutside = false


    -- Now we loop and check if player is in the Area
    -- Numeric loops are more efficient than for k, v in pairs() do loops.
    for i = 1, #PartsInside do
        local Part = PartsInside[i] -- gets the part

        local Parent = Part.Parent -- gets the parent part, in order to check for humanoids to
        -- make this a bit more efficient
        local Humanoid = Parent:FindFirstChildOfClass("Humanoid")
        if Humanoid then
            local Player = Players:GetPlayerFromCharacter(Parent)  -- Gets player
            if Player == Client then -- Checks if the player is Client, if it is then it proceeds
                --to play audio and set PlayerOutside to true
                PlayerInside = true
                if not InsideAudio.Playing then -- checks if it's not playing. if it isn't then 
                -- it plays the sound. this is to prevent it repeatedly playing
                    InsideAudio:Play()
                end
                break
            end
        end
    end
    for i = 1, #PartsOutside do
        local Part = PartsOutside[i] -- gets the part

        local Parent = Part.Parent -- gets the parent part, in order to check for humanoids to
        -- make this a bit more efficient
        local Humanoid = Parent:FindFirstChildOfClass("Humanoid")
        if Humanoid then -- Checks if humanoids Exists
            local Player = Players:GetPlayerFromCharacter(Parent) -- Gets player
            if Player == Client then -- Checks if the player is Client, if it is then it proceeds
                --to play audio and set PlayerOutside to true
                PlayerOutside = true
                if not OutsideAudio.Playing then -- checks if it's not playing. if it isn't then 
                -- it plays the sound. this is to prevent it repeatedly playing
                    OutsideAudio:Play()
                end
                break
            end
        end
    end

    if not PlayerInside and InsideAudio.Playing then -- Checks if Player isn't inside and 
    -- InsideAudio is playing, which if that is true it stops the audio
        InsideAudio:Stop()
    end
    if not PlayerOutside and OutsideAudio.Playing then -- Checks if Player isn't Outside and 
    -- OutsideAudio is playing, which if that is true it stops the audio
        OutsideAudio:Stop()
    end

    -- This does not check whether or not player is both outside and inside meaning Audio's 
    -- might overlap.
end

Connection = RunService.Heartbeat:Connect(Check)
--[[Now I reference the connection with the variable here; 
Why I am using Heartbeat instead of RenderStepped
is because it is not really that important if it's slightly delayed,
as using RenderStepped can slow down the game a lot while rendering, 
leading to bad player experience.]]

Sources

https://developer.roblox.com/en-us/api-reference/function/WorldRoot/FindPartsInRegion3 https://developer.roblox.com/api-reference/function/Players/GetPlayerFromCharacter https://developer.roblox.com/en-us/api-reference/event/RunService/Heartbeat https://developer.roblox.com/en-us/api-reference/datatype/RBXScriptConnection

I hope this answer was helpful, and I'm sorry if this answer is slightly bad, I'm slightly inexperienced with answering. Feel free to ask further.

Cheers, Luke.

Edit Updated the code very slightly to not repeatedly play sound's if they are inside the Area.

0
Woah woah. Slow down there, pal. Why on Earth would I need a Region3 to play audio? But thanks for answering, I might take this into consideration. Sensei_Developer 298 — 4y
0
Region3's fit well for what you want. Region3's are pretty much designed for stuff like this. guidable 42 — 4y
Ad

Answer this question