How can I make a command run once in a function that runs every second

Godot Version

4

Question

For more context In my game I am checking whether or not you are in the main screen, settings, or game. depending on this different music will play. Problem is I have to check for that constantly and that means it plays constantly. Can somebody help me create a better version?

You can just change the music whenever the player changes the screen they are on.

send a signal to your “core” or main game controller to play a certain bgm when switching to those scenes. no need to check it every frame

2 Likes

Do you mind showing a example. I’m not sure what you mean

By the way I have my sounds played on a Autoload script so that it can play through multiple scenes but I’m Having trouble stopping it. And because its not part of the actual scene I can’t just look up the audio streamer and stop it.

I don’t see why you can’t address an autoload. If you have an autoloded script that’s called, say, my_audio_player, you can totally target it with something like MyAudioPlayer.play() from any node in the tree, that ease of access is kinda one of the points of having a singleton. And if for some reason your game doesn’t recognize that name, you can always explicitly write “class_name MyAudioPlayer” (right before “extends…”) With that, you can get rid of constant checks and just tell the autoload to change music whenever the player enters another screen.

1 Like

Thanks so much! I’m new to godot so I’m still learning the engine so that’s a big help

main_menu.gd

func _ready():
	...
	await get_tree().create_timer(0.5).timeout
	EventBus.emit_signal("play_bgm", main_menu_bgm)

audio_manager.gd

@export var bgm_player: AudioStreamPlayer2D

func _ready():
	EventBus.play_bgm.connect(play_bgm)

func play_bgm(bgm_file: AudioStream):
	...
	
	if (bgm_player.stream != bgm_file):
		bgm_player.stream = bgm_file
		bgm_player.play()
		
		...

EventBus.gd (autoload script)

signal play_bgm(bgm_file: AudioStream)

something like this to play a bgm with signal, this one send signal directly to audio manager which here is not an autoload, but a pre-deployed scene on a Core scene tree with a child of AudioStreamPlayer2D

to stop playing the bgm when switching scene tho, you also need to send the signal

EventBus.gd (autoload script)
signal stop_bgm

core.gd

func switch_scene(scene_path: String,level=-1):
	var current_scenes = scene_node_container.get_children()
	var scene_count: int = current_scenes.size()
	
	if (scene_count > 0):
		...
		EventBus.emit_signal("stop_bgm")

audio_manager.gd

func stop_bgm():
	bgm_player.stop()
1 Like

Now I’m having trouble getting it. I tried getting it by doing Sounds.MainMenuMusic (As my audio streamer is MainMenuMusic and the auto load file is Sounds) but its not working. What did I do wrong?

Never mind I found out how.

Never mind it doesn’t work anymore. I have a variable for music and if its turned of and on again then the music only plays after the main scene is opened again. How do I fix this?

which approach you use for this again? the Sounds autoload? or the one i shared with pre-deployed AudioStreamPlayer2D that wont be gone when switch scene?

Autoload. Btw I fixed it but the solution is super complicated so I’m up for anything else

I basically made a variable to say if the music was false it would make the variable 1 and if it was 1 and music was turned on then it becomes 2. If it was 2 music would play and if it was previously in the arena then it becomes a 0 and the music plays. That’s somewhat of how it works but its really wrong