Playing a sound a total of one time for multiple instances of the same script activating at the same time

Hello! Basically title, I have 3 enemies that are all copies of each other, and they all do the same move at the same time (turn based game), and if I put a sound to play in the script, they will overlap and be like 3x as loud. How would I go about telling either the enemy or the sound player to only play it once when called 3 times?

1 Like

Are you using AudioStreamPlayer or AudioStreamPlayer2D or AudioStreamPlayer3D? If you’re using the 2D or 3D player, then you might lose the positional information about the sound when you play it only once for 3 enemies.

Share your code snippet where you start playing the sound please, using the preformatted text ``` for the code.

extends Node

func play(audio: AudioStream, single = false) -> void:
	if not audio:
		return
	
	if single:
		stop()
	
	for player in get_children():
		player = player as AudioStreamPlayer
		
		if not player.playing:
			player.stream = audio
			player.play()
			break

func stop() -> void:
	for player in get_children():
		player = player as AudioStreamPlayer
		player.stop()

This is my SFXPlayer, its global and is called from a lot of places, including the enemies and all their moves and statuses

Simple fix could be to check if any of the players is already playing this AudioStream and if yes - then return early from the method. Let me know if that works for you.

extends Node

func play(audio: AudioStream, single = false) -> void:
	if not audio:
		return
	
	if single:
		stop()
	
	for player in get_children():
		player = player as AudioStreamPlayer
		if player.playing and player.stream == audio:
			return
	
	for player in get_children():
		player = player as AudioStreamPlayer
		
		if not player.playing:
			player.stream = audio
			player.play()
			break

func stop() -> void:
	for player in get_children():
		player = player as AudioStreamPlayer
		player.stop()
2 Likes

Thanks! This mostly worked, but instead of just checking if its playing the same audio, I had to add a parameter to the play function to make each sound custom if it should cancel or not, because if a sound is still playing and it gets repeated shortly after, like spamming the attack button, it should still play.

extends Node

func play(audio: AudioStream, single = false, count = 0) -> void:
	if not audio:
		return
	
	if single:
		stop()
	
	if count > 0:
		var amount = 0
		for player in get_children():
			if player.stream == audio and player.playing:
				amount += 1
				if amount >= count:
					return
	
	for player in get_children():
		player = player as AudioStreamPlayer
		
		if not player.playing:
			player.stream = audio
			player.play()
			break

func stop() -> void:
	for player in get_children():
		player = player as AudioStreamPlayer
		player.stop()
2 Likes