2021-02-26 20:58:13 +01:00
extends Node3D
2020-09-19 11:22:41 +02:00
# This Scene is meant for playing back sound groups. For simple, singular sound effects use stock Godot nodes, this is meant to play a random sound among a group with variations.
const SFX_dir = " res://Assets/SFX/ " # all sound clips must reside somewhere in this directory
2021-02-26 20:58:13 +01:00
@ onready var player = $ AudioStreamPlayer3D # playback backend
2020-09-19 11:22:41 +02:00
2020-09-19 12:38:23 +02:00
export ( String , FILE , " *-01.wav " ) var SoundClip = SFX_dir + " Test-01.wav "
2020-09-19 12:45:14 +02:00
export ( bool ) var AutoPlay = false
2020-09-19 12:38:23 +02:00
export ( float ) var MinimumRandomDistance = 0.35 # gives optimal playback repetition for sound clip groups of different sizes.
export ( bool ) var PlayUntilEnd = false # determines if the play() function is allowed to sop a previously started sound
export ( float ) var MinDelay = 0 # determines how many seconds must pass before the sound can be triggered again
2020-09-26 01:06:56 +02:00
export ( float ) var PitchScale = 1
export ( float ) var RandomizePitch = 0
2020-09-19 11:22:41 +02:00
var min_distance = 0 # this determines how ofte na sound is allowed to play (any Nth time) this is calculated automatically based on maximum_repetition
var clips = [ ] # holds loaded sound stream resources
var recently_played = [ ] # holds indexes of recently played
2020-09-19 12:38:23 +02:00
var ready = true # used as a semaphor for MinDelay
2020-09-19 11:22:41 +02:00
# Called when the node enters the scene tree for the first time.
func _ready ( ) :
var files = [ ]
var dir = Directory . new ( )
dir . open ( SFX_dir )
dir . list_dir_begin ( )
#print("SoundClip: ", SoundClip)
var group = SoundClip . left ( SoundClip . find_last ( ' - ' ) ) . right ( SoundClip . find_last ( ' / ' ) + 1 )
2020-09-26 00:56:52 +02:00
#print("group: ", group)
2020-09-19 11:22:41 +02:00
while true :
var file = dir . get_next ( )
#print(file)
if file == " " :
break
elif not file . begins_with ( " . " ) and file . begins_with ( group ) and file . ends_with ( " .wav " ) :
files . append ( file )
dir . list_dir_end ( )
2020-09-26 00:56:52 +02:00
#print(files)
2020-09-19 11:22:41 +02:00
for f in files :
clips . append ( load ( SFX_dir + f ) )
2020-09-19 12:38:23 +02:00
min_distance = floor ( len ( clips ) * MinimumRandomDistance )
2020-09-19 11:22:41 +02:00
2020-09-26 00:56:52 +02:00
#print ("Clips: ", len(clips))
#print ("min_distance: ", min_distance)
2020-09-19 12:45:14 +02:00
if AutoPlay :
play ( )
2020-09-19 12:38:23 +02:00
func pick_random ( ) :
return randi ( ) % len ( clips )
2020-09-19 11:22:41 +02:00
2020-09-28 00:06:43 +02:00
sync func play ( ) :
2020-09-19 12:38:23 +02:00
if PlayUntilEnd :
if player . playing :
return 1
if MinDelay > 0 :
if not ready :
return 2
var i = pick_random ( )
while recently_played . has ( i ) :
i = pick_random ( )
2020-09-26 00:56:52 +02:00
#print("i: ", i)
2020-09-19 12:38:23 +02:00
recently_played . append ( i )
if len ( recently_played ) > min_distance :
recently_played . remove ( 0 )
2020-09-26 00:56:52 +02:00
#print("recently played: ", recently_played)
2020-09-19 12:38:23 +02:00
player . stream = clips [ i ]
2020-09-26 01:06:56 +02:00
if RandomizePitch != 0 :
player . pitch_scale = PitchScale + rand_range ( - RandomizePitch / 2 , RandomizePitch / 2 )
else :
player . pitch_scale = PitchScale
2020-09-19 11:22:41 +02:00
player . play ( )
2020-09-19 12:38:23 +02:00
ready = false
yield ( get_tree ( ) . create_timer ( MinDelay ) , " timeout " )
ready = true
2020-09-19 11:22:41 +02:00
# TODO implement final randomization algorithm
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass