Skip to content

Instantly share code, notes, and snippets.

@GammaGames
Last active February 14, 2025 07:20
Show Gist options
  • Save GammaGames/3ddc8da2d577c3115a3aa1cb793c07c2 to your computer and use it in GitHub Desktop.
Save GammaGames/3ddc8da2d577c3115a3aa1cb793c07c2 to your computer and use it in GitHub Desktop.
A simple sound effect resource + scene
class_name SoundBoard extends Resource
@export var streams : Dictionary[String, AudioStream] = {}
# Config vars should be in the format:
# "type:property" : "value"
# "ready:max_distance" : "25.0"
# "attack:volume_db" : "-10.0"
@export var config : Dictionary[String, String] = {}
@export var default_distance := 10.0
func setup(target : Node, type = null) -> void:
if type:
_setup(target, type)
else:
for _type in self.streams:
_setup(target, _type)
func _setup(target : Node, type: String) -> void:
# Create 2d or 3d automatically
var player = AudioStreamPlayer3D.new() if target is Node3D else AudioStreamPlayer2D.new()
player.name = "%s_sounds" % type
player.stream = self.streams[type]
player.max_distance = default_distance
for key in self.config:
var parts = key.split(":")
if parts[0] == type:
player.set(parts[1], self.config[key])
if type == "ready":
player.autoplay = true
target.add_child(player)
func play(target : Node, type: String):
if self.streams.has(type):
var node = target.get_node_or_null("%s_sounds" % type)
if not node:
self.setup(target, type)
node = target.get_node("%s_sounds" % type)
node.play(0)
return node
func stop(target : Node, type: String):
if not type:
for _t in self.streams:
target.get_node("%s_sounds" % _t).stop()
if self.streams.has(type):
target.get_node("%s_sounds" % type).stop()
func clone(target: Node, type: String) -> Variant:
if self.streams.has(type):
var node = target.get_node_or_null("%s_sounds" % type)
if not node:
self.setup(target, type)
node = target.get_node("%s_sounds" % type)
return node.duplicate()
return null
func has(type: String) -> bool:
return self.get(type) != null
class_name Sounds extends Node
# Attach this to whatever scene you want
@export var soundboard : SoundBoard
@export var lazy : bool = true
func _ready() -> void:
if soundboard:
if not lazy:
soundboard.setup(self)
elif "ready" in soundboard.streams:
soundboard.setup(self, "ready")
func play(type: String):
if soundboard:
return soundboard.play(self, type)
static func _play_global(stream, position) -> void:
Engine.get_main_loop().get_current_scene().add_child(stream)
if position:
stream.global_position = position
stream.play(0)
await stream.finished
stream.queue_free()
func play_global(type: String):
if soundboard:
var clone = soundboard.clone(self, type)
if clone:
Sounds._play_global(clone, self.global_position)
func stop(type):
if soundboard:
soundboard.stop(self, type)
func has(type: String) -> bool:
if soundboard:
return soundboard.has(type)
return false
@GammaGames
Copy link
Author

GammaGames commented Jan 18, 2025

To use it:

@onready var sounds : Sounds = $Sounds

func my_func() -> void:
    sounds.play("key")

And the setup in the inspector:
image

If you want something to play on spawn, you can use ready as a key:
image

https://bsky.app/profile/gammagames.bsky.social/post/3lfyoglpui22d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment