extends Node # SFXManager - Global singleton for playing sound effects # Autoloaded as "SfxManager" var sounds: Dictionary = {} func _ready(): _load_sounds() func _load_sounds(): var sfx_path = "res://assets/sfx/" var dir = DirAccess.open(sfx_path) if dir: dir.list_dir_begin() var file_name = dir.get_next() while file_name != "": if not dir.current_is_dir(): # Remove .import extension if it exists (Godot adds this to imported resources in exported builds) var clean_name = file_name.replace(".import", "") if clean_name.ends_with(".mp3") or clean_name.ends_with(".wav") or clean_name.ends_with(".ogg"): var base_name = clean_name.get_basename() # Ex: "jump.wav" -> "jump" # Only load the original extension, Godot's resource loader handles the .import remapping automatically. if not sounds.has(base_name): sounds[base_name] = load(sfx_path + clean_name) file_name = dir.get_next() dir.list_dir_end() else: push_error("[SfxManager] Could not open sfx directory: " + sfx_path) func play(sound_name: String, pitch_range: float = 0.0): if not sounds.has(sound_name): # push_warning("[SfxManager] Sound not found: " + sound_name) return var player = AudioStreamPlayer.new() add_child(player) player.stream = sounds[sound_name] player.bus = "SFX" if pitch_range > 0: player.pitch_scale = 1.0 + randf_range(-pitch_range, pitch_range) player.play() player.finished.connect(player.queue_free) @rpc("any_peer", "call_local", "unreliable") func play_rpc(sound_name: String, pitch_range: float = 0.0): play(sound_name, pitch_range)