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.
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)
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!
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.