So basically from the top, I have two accessories welded to a player which looks like this.
And there’s a button attached and when the player clicks it, an animation plays which looks like this.
Im trying to make it so the whistle makes sound. I know you can just put a sound in the accessory and script it so it plays but you can’t really do that.
You see, the two accessories are in ServerStorage and it gets cloned into the player.
Now, when you click that button you see in the top left of the video, I want it to make the sound plays. Now I’ve tried making it so when you click it, it creates a Sound in the player and it plays and after its been played, it deletes itself and when you click the button again, it does it again and so on but I don’t know how to do that.
local hat = -- path to hat
local Sound = Instance.new("Sound", hat)
Sound.SoundId = "rbxassetid://ID"
Sound:Play()
wait(Sound.TimeLength)
Sound:Destroy()
If you don’t care about the sound playing exactly when the animation shows the player playing a whistle, you can create a new instance of the sound, give it the soundid, parent it to the player’s accessory, play it, wait until it is finished and then destroy it.
IF you do care about the sound playing as soon as the animatino reaches the point of the whistle being near the mouth, you need to go the animation through the editor and rename the keyframe where the whistle is near your mouth, something like “PlaySound”, then you get the track and use KeyframeReached, which only fires on keyframes whose name is not Keyframe
Though if the aniamtion is played on the client and you plan on playing the sound through the server for everyone to hear, you’ll need a remote event for that. But as a showcasing example
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://SOUNDIDHERE"
sound.Parent = pathToHatHere
AnimationTrack.KeyframeReached:Connect(function(keyframeName)
if keyframeName == "PlaySound" then
sound:Play()
sound.Ended:Wait()
sound:Destroy()
end
end)
I dont recommend using wait(sound.TimeLength) if there’s event based approaches for what you want to do, in this case, wait for a sound to finish playing, use the event instead.
For what you want, I think you may need to have the script alreayd put in the accessory as when it is cloned to the player, should make the script run again
Then in your case you may need to do the 2nd approach if you care about the sound playing when the whistle is near your mouth, though you willl need to create the sound inside of the event and not outside of it
But if you just want to play it when the button is pressed, then in both cases you definitely need a RemoteEvent.
When the event is fired to the server, it creates the sound, puts it in the path you give it, plays it, then destroys it after it is done. The script for the OnServerEvent will need to probably be i nServerScriptService and not in the accessory
May you explain more thoroughly on what to do? I only care about the whistle being near the mouth. Like where to put the scripts etc. I’ll send a picture of the explorer down below.
The two accessories highlighted in red.
The GUI you click on to play the animation
The script which puts the accessories into the player
this is exactly what you need along a remote event to play the sound.
Animation events grant sync.
I personally dislike making a remote for every single thing so let’s just make a general emote remote, I’ll edit as I go on.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage.Emote
youranimation:GetMarkerReachedSignal("Emote"):Connect(function()
Event:FireServer(--Put whatever parameter you want here, sound Id, command string, whatever you want to recognize it on the server)
end)
replace youranimation with the loaded animation track of yours, and read the uncoded text.
Now we need to set the animation event.
Export your animation with the event.
Make sure it’s named “Emote”, or change it to anything else as long as both are the same string.