ALEXPOW Posted July 16 Share Posted July 16 Basic backstory, new to scripting. Not quite sure how to aptly title this. I'm looking for a way to have a crafting station repeatedly play a sound descriptor every so often with the use of a script. The end product I'm hoping to achieve is a Crafting Station that will idly play a sound descriptor, wait between 5-10 minutes, and play a sound descriptor again. All of that without having to interact with the crafting station in the first place. If I must have it be done via interaction, that is okay. The main thing I want is the repeated sound descriptor. I don't want it to play a sound descriptor that is looping, as that only seems to play a single audio file and not a random one from the descriptor (unless I got unlucky on the activations). Currently, I only have a simple script that will play the sound descriptor whenever the item is interacted with. Not exactly what I want, especially since repeated interactions will cause the sound to overlap and destroy my eardrums. Spoiler Scriptname RCA_JuggernogJukeboxScript:RCA_JuggernogJukeboxScript extends ObjectReference Const {The script that plays the Juggernog Perk Jingle on-loop} Sound Property RCA_JuggernogJingle Auto Const Event OnActivate(ObjectReference akActionRef) RCA_JuggernogJingle.PlayAndWait(Self) EndEvent I also attached a picture of the Sound Descriptor, if that could help explain things. As a side note, I would like to know if there's a way I can make it so that proximity to the crafting station plays a sound descriptor, as if bumping into it. This has nothing to do with the above request's script or sound descriptor, it would be completely separate. Link to comment Share on other sites More sharing options...
LarannKiar Posted July 17 Share Posted July 17 Something like this should work: Scriptname RCA_JuggernogJukeboxScript:RCA_JuggernogJukeboxScript extends ObjectReference Const {The script that plays the Juggernog Perk Jingle on-loop} Sound Property RCA_JuggernogJingle Auto Const Event OnLoad() ; the ObjectReference this script is attached to is 3D loaded PlayCustomSound() ; call the main sound play function defined below EndEvent Event OnTimer(int aiTimerID) ; code the behavior of this function If aiTimerID == 555 If Self.Is3DLoaded() == true ; when you attach a script to non persistent object reference which has a timer, it's generally recommended to check if it's 3D loaded PlayCustomSound() EndIf EndIf EndFunction Event OnUnload() ; the ObjectReference this script is attached to is 3D unloaded CancelTimerGameTime(555) ; cancel the game time timer whose aiTimerID is 555 EndEvent Function PlayCustomSound() ; code of the function If Game.GetPlayer().GetDistance(Self) <= 1000 ; player is within 1000 game units to this reference RCA_JuggernogJingle.Play(Self) ; play the sound StartTimerGameTime(0.25, 555) ; restart the timer EndIf EndFunction Link to comment Share on other sites More sharing options...
ALEXPOW Posted July 19 Author Share Posted July 19 I was only able to get the sound to play once on load with this, it didn't seem to ever trigger again. Unless I didn't wait long enough. Link to comment Share on other sites More sharing options...
DieFeM Posted July 19 Share Posted July 19 I'd say the timer should be outside of the distance conditional. Function PlayCustomSound() ; code of the function If Game.GetPlayer().GetDistance(Self) <= 1000 ; player is within 1000 game units to this reference RCA_JuggernogJingle.Play(Self) ; play the sound EndIf StartTimerGameTime(0.25, 555) ; restart the timer EndFunction That way it will continue looping the timer, even if you are more than 1000 units away, until it unloads. Link to comment Share on other sites More sharing options...
LarannKiar Posted July 19 Share Posted July 19 6 hours ago, DieFeM said: I'd say the timer should be outside of the distance conditional. Function PlayCustomSound() ; code of the function If Game.GetPlayer().GetDistance(Self) <= 1000 ; player is within 1000 game units to this reference RCA_JuggernogJingle.Play(Self) ; play the sound EndIf StartTimerGameTime(0.25, 555) ; restart the timer EndFunction That way it will continue looping the timer, even if you are more than 1000 units away, until it unloads. You're right. The distance check was actually an afterthought. Link to comment Share on other sites More sharing options...
RaidersClamoring Posted July 19 Share Posted July 19 You should keep the handle you get when starting the sound if you want more fine-grained control over how and for how long it's played. It's an integer that is acquired when calling <sound>.Play(ObjectReference). e.g.: "int instanceID = mySFX.play(self)" You can then cancel the playback at any point by calling Sound.StopInstance(instanceID). You can also manipulate the volume using the handle. Read more here: https://falloutck.uesp.net/wiki/Sound_Script Link to comment Share on other sites More sharing options...
niston Posted July 20 Share Posted July 20 Why don't you set the descriptor to loop ? There's currently no way for a script to get notified when a sound started via Play() has ended. A script can't even check if the sound is still playing rn. All that will change soon (TM). Link to comment Share on other sites More sharing options...
ALEXPOW Posted July 20 Author Share Posted July 20 12 hours ago, niston said: Why don't you set the descriptor to loop ? There's currently no way for a script to get notified when a sound started via Play() has ended. A script can't even check if the sound is still playing rn. All that will change soon (TM). The sound descriptor doesn't shuffle between different audio files when it is set to loop, as far as I know. It just picks one on the initial call and sticks with it until it is ended and called again. I would prefer it to shuffle between the audio files randomly. Link to comment Share on other sites More sharing options...
ALEXPOW Posted July 23 Author Share Posted July 23 Big thanks, everyone! Got it working. I found using a normal timer over a Game Time timer worked better. I hope that doesn't cause any issues that I'm unaware of. I have attached the script I used for anyone in the future. (Note: I added another sound that plays when the machine loads in for the first time, and added a ~30 second buffer of silence to the repeating sound's .wav files.) Spoiler Scriptname RCA_JuggernogJukeboxScript:RCA_JuggernogJukeboxScript extends ObjectReference Const {The script that plays the Juggernog Perk Jingle on-loop} Sound Property RCA_JuggernogJingle Auto Const Sound Property RCA_PerkMachinePlacedFirstTime Auto Const Event OnLoad() ; the ObjectReference this script is attached to is 3D loaded RCA_PerkMachinePlacedFirstTime.Play(Self) ; Plays a unique sound that does not repeat when the timer is reset PlayCustomSound() ; call the main sound play function defined below EndEvent Event OnTimer(int aiTimerID) ; code the behavior of this function If aiTimerID == 555 If Self.Is3DLoaded() == true ; when you attach a script to non persistent object reference which has a timer, it's generally recommended to check if it's 3D loaded PlayCustomSound() EndIf EndIf EndEvent Event OnUnload() ; the ObjectReference this script is attached to is 3D unloaded CancelTimerGameTime(555) ; cancel the game time timer whose aiTimerID is 555 EndEvent Function PlayCustomSound() ; code of the function If Game.GetPlayer().GetDistance(Self) <= 1000 ; player is within 1000 game units to this reference RCA_JuggernogJingle.Play(Self) ; play the sound EndIf StartTimer(300, 555) ; restart the timer EndFunction Again, huge thanks to everyone involved! 1 Link to comment Share on other sites More sharing options...
DieFeM Posted July 23 Share Posted July 23 Repalce CancelTimerGameTime with CancelTimer. Link to comment Share on other sites More sharing options...
Recommended Posts