3 part horns are horns that you can make go on for any amount of time. They use a beginning audio, a middle audio, which can be looped, and an end audio. I have tried before to make this, but it didn’t work. I don’t know where the script is anymore. Anyway, how would I make this? I can’t find anything on how to do it.
Several ways, you could have the sequence just wait for the previous sound to finish playing before starting, have them fade volumes in/out, etc. I always used the TF2 minigun as an example of this sound behavior:
Player begins holding mouse1, the “wind up” audio plays. As soon as that soundfile finishes, it starts playing the “firing” audio. If at any point the player stops holding mouse1, both the wind up and fire audios are immediately stopped, and the “wind down” audio is started.
In code, you could make them play in order like this:
script.windup:Play() repeat task.wait() until not script.windup.IsPlaying--IsPlaying == false when its finished script.fire:Play() repeat task.wait() until not script.fire.IsPlaying--needs different break point if its looping script.winddown:Play() repeat task.wait() until not script.winddown.IsPlaying
How would I make that break with the looping audio? I have tried detecting when the player stops holding H, it will set HornLoop.IsPlaying to false, but for some reason the horn never stops
:Stop() on the sound instead,
.isPlaying is a read-only boolean. You may be thinking of
.Playing which can be manually set, but that’s for pausing/resuming and I’m not sure how reliable/optimal that would be in this case.
I have no idea why my brain just removed :Stop() from itself.
Ok, it still repeats forever. Here is the script (Not the entire thing, just the important part)
repeat task.wait() until not HornStart.IsPlaying--IsPlaying == false when its finished HornLoop:Play() repeat task.wait() until not HornLoop.IsPlaying--needs different break point if its looping UIS.InputEnded:Connect(function(key) if key.KeyCode == Enum.KeyCode.H then HornLoop:Stop() end end) HornEnd:Play() repeat task.wait() until not HornEnd.IsPlaying
I see it. Delete the
repeat task.wait() until not HornLoop.IsPlaying as this will yield the script infinitely, since it’s waiting for an infinite sound to stop playing. Reorder it to look something like:
repeat task.wait() until not HornStart.IsPlaying HornLoop:Play() UIS.InputEnded:Connect(function(key) if key.KeyCode == Enum.KeyCode.H then HornLoop:Stop() HornEnd:Play()--play the end *inside* the InputEnded for it to work as intended repeat task.wait() until not HornEnd.IsPlaying end end)
Just tried this, and it still loops infinitely
Can you put a debug statement (like
print("H")) inside the
if key.KeyCode == ... part to see that the button is triggering it properly?
It does not seem to be printing anything.
Ok, your script may be held up somewhere before the InputEnded connection is made. “H” might also be getting observed internally, you can check that by changing your function to this:
UIS.InputEnded:Connect(function(key, gameProcessed) if(gameProcessed) then print("input was processed internally") return end if key.UserInputType == Enum.UserInputType.Keyboard then print(key.KeyCode .. " has been released!") if key.KeyCode == Enum.KeyCode.H then HornLoop:Stop() print("Horn stopped!") HornEnd:Play()--play the end *inside* the InputEnded for it to work as intended end end end)
Ensure that HornStart and HornEnd are not set to loop, only HornLoop should be.
*Edited to catch if InputType wasn’t a keyboard so the script wouldn’t crash
Still does not seem to work, and it also prints nothing
Ok, so the connection is never made. Somewhere prior to that in the code the script is yielding. Anywhere above it that it’s waiting for something? Another infinite task.wait() loop maybe?
Or… is this in a server-sided script? UIS has to be captured in a LocalScript.
It’s in a ModuleScript. I wasn’t sure how the game would react to having UIS in a ModuleScript, and I really can’t do anything else, so I tried it
Ok, so this should be done with Remote Events then. Have a localscript capturing UIS inside each player and have them fire an event when they begin and end pressing H. I’d recommend a single event for both and fire a boolean along with it (such that when they begin they fire “true”, when they finish they fire “false”).
Alternatively you could restructure it to be triggered by something the server can see, like a .Touched event or a button in workspace.