The scripts and sounds works weirdly in replicated storage.
Sounds play automatically in replicated storage on start, client scripts as well, legacy scripts copied from replicated storage doesn’t play.
What I would achieve:
I would make my projectile have sound. I have projectile templates in the replicated storage. I clone them and shoot them. It works.
It has sound and it is parented to the projectile. I want these sounds play automatically when the bullet is spawned.
The desired structure:
Bullet
–Sound (Sound)
----SoundPlay (Script)
SoundPlay script content (it doesn’t rly matter regarding the problem)
script.parent:Play()
Problems:
- sounds plays automatically at the replicated storage at game start
- scripts with Client RunContext runs automatically in the replicated storage at game start
- scripts with Legacy RunContext doesn’t play when cloned
My steps so far:
I have the projectile. I parented a sound under it and sat it into Playing. It is not good because it runs at start. Then I sat the playing to false and added a script that starts the sound.
But it doesn’t work when I clone the projectile. I sat the script runcontext to client. Now the script runs when I copy it, but it runs at the start in the replicated storage as well. So the sounds plays at the start.
Now my hotfix is that I modified my script like this:
if script:IsDescendantOf(game.ReplicatedStorage) then
return
end
script.parent:Play()
This works, but feels like a hack. Is this typical Roblox behavior, or am I missing something?
Is my wish to have automatic sound play in a template is too unusual for Roblox?
This is my full script now. Just a reference to show what I would achieve.
if script:IsDescendantOf(game.ReplicatedStorage) then
return
end
local soundList : string = {}
for _,c in ipairs(script.Parent:GetChildren()) do
if c:IsA("StringValue") then
table.insert(soundList, c.Value)
end
end
local speaker : Sound = script.Parent
local speakerTarget : BasePart = speaker.Parent
if speakerTarget:IsA("Model") then
speakerTarget = speakerTarget.PrimaryPart
end
--settings coming here
if #soundList > 0 then
speaker.SoundId = soundList[math.random(1, #soundList)]
end
if script.Parent:FindFirstChild("minVolume") and script.Parent:FindFirstChild("maxVolume") then
speaker.Volume = math.random(script.Parent.minVolume.Value, script.Parent.maxVolume.Value)
end
--setting end
local soundP = workspace:FindFirstChild("SoundInstances")
if not soundP then
soundP = Instance.new("Folder")
soundP.Name = "SoundInstances"
soundP.Parent = workspace
end
local holder = Instance.new("Part")
holder.Parent = soundP
holder.Position = speakerTarget.Position
holder.Transparency = 0
holder.CanCollide = false
holder.CanTouch = false
holder.CanQuery = false
holder.Anchored = false
holder.Massless = true
if script.Parent.doFollow and script.Parent.doFollow.Value then
local weldConstraint = Instance.new("WeldConstraint")
weldConstraint.Parent = speakerTarget
weldConstraint.Part0 = speakerTarget
weldConstraint.Part1 = holder
end
speaker.Parent = holder
speaker.Ended:Connect(function(id)
holder:Destroy()
end)
speaker:Play()