Music resets itself when Settings Button is clicked

Godot Version

Godot_v4.3-stable_mono_win64

Question

So basically, I am coding a game where you can play ultimate tic tac toe and simple tic tac toe, But when I start the game, the music works, but as soon as I click the SettingsButton, the song restarts itself again, any reason why? I have been troubleshooting this for about an hour now and cant seem to find why, please help.

Here is a video to show exactly whats happening

here is settingspopup.gd (where the settingspopup is)

extends Popup

# Member variables for controls
var volume_slider: HSlider
var sfx_mute: CheckButton
var save_button: Button
var close_button: Button
var color_rect: ColorRect
var vbox_container: VBoxContainer
var vibes_player: AudioStreamPlayer

func _ready():
	vbox_container = get_node("VBoxContainer")
	volume_slider = vbox_container.get_node("Volume_Slider")
	sfx_mute = vbox_container.get_node("SFXMute")
	save_button = vbox_container.get_node("Save_Button")
	close_button = vbox_container.get_node("Close_Button")
	color_rect = get_node("ColorRect")

	color_rect.show()
	color_rect.color = Color(0.3, 0.3, 0.3, 1)  # Set to a darker gray
	color_rect.size = Vector2(100, 150)  # Adjust the size as needed

	# Set the size of the popup
	size = Vector2(300, 150)  # Adjusted for better visibility
	popup()

	# Adjust size flags
	vbox_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	vbox_container.size_flags_vertical = Control.SIZE_EXPAND_FILL

	# Initialize controls based on config settings
	initialize_controls()

	# Call the method to connect signals
	_connect_signals()

func initialize_controls():
	load_mute_state()

	# Adjust this path based on your scene hierarchy
	vibes_player = get_node("/root/Control/VibesPlayer")  # Adjust the path based on your hierarchy
	if vibes_player:  # Ensure it's not null
		vibes_player.stream = load("res://vibes.ogg")  # Ensure this path is correct
		if not vibes_player.playing:
			vibes_player.play()  # Start playing music

func _on_CloseButton_pressed():
	hide()
	print("Popup closed")

# Function to mute/unmute SFX AudioStreamPlayers
func update_sfx_mute_state(is_muted: bool):
	var sfx_manager = get_node("/root/SFXManager")
	if sfx_manager:
		sfx_manager.set_mute_state(is_muted)  # Update global mute state
	else:
		print("SFXManager is not found!")

# Call this when the user toggles the SFX mute state in the settings menu
func _on_SFXMute_pressed():
	var is_muted = sfx_mute.is_pressed()  # Corrected here
	update_sfx_mute_state(is_muted)  # Update global state

# Load the mute state from the config file
func load_mute_state():
	var config = ConfigFile.new()
	if config.load("user://settings.cfg") == OK:
		var is_muted = config.get_value("audio", "sfx_mute", false)
		sfx_mute.set_pressed(is_muted)  # Set the button state based on the config
		update_sfx_mute_state(is_muted)  # Apply the mute state

# Function to save the mute state in settings.cfg
func save_mute_state(is_muted: bool):
	var config = ConfigFile.new()
	config.load("user://settings.cfg")
	config.set_value("audio", "sfx_mute", is_muted)  # Save the mute state
	config.save("user://settings.cfg")  # Write to disk

func _connect_signals():
	if not volume_slider.is_connected("value_changed", Callable(self, "_on_Volume_Slider_value_changed")):
		volume_slider.connect("value_changed", Callable(self, "_on_Volume_Slider_value_changed"))
	
	if not sfx_mute.is_connected("pressed", Callable(self, "_on_SFXMute_pressed")):
		sfx_mute.connect("pressed", Callable(self, "_on_SFXMute_pressed"))
	
	if not save_button.is_connected("pressed", Callable(self, "_on_SaveButton_pressed")):
		save_button.connect("pressed", Callable(self, "_on_SaveButton_pressed"))
	
	if not close_button.is_connected("pressed", Callable(self, "_on_CloseButton_pressed")):
		close_button.connect("pressed", Callable(self, "_on_CloseButton_pressed"))

# Function to handle volume slider value change
func _on_Volume_Slider_value_changed(value: float):
	if vibes_player:  # Ensure it's not null
		# Map the slider value back to dB for the vibes_player
		vibes_player.volume_db = value / 100 * 60 - 60  # Convert 0-100 to -60 to 0 dB

	if sfx_mute.is_pressed() and value > 0:
		sfx_mute.set_pressed(false)  # Unmute if volume is adjusted above 0

# Function to handle save button pressed
func _on_SaveButton_pressed():
	print("Save button pressed")
	var volume_value = volume_slider.value
	var is_muted = sfx_mute.is_pressed()  # Corrected here
	save_mute_state(is_muted)  # Save the mute state
	print("Volume:", volume_value)
	print("SFX Mute:", is_muted)

Ui.gd (The main scene with the music)

extends Control

var credits_popup: Popup = null
var settings_popup: Popup = null
var button_click_player: AudioStreamPlayer = null  # Reference to the AudioStreamPlayer
var music_player: AudioStreamPlayer = null  # Reference to the AudioStreamPlayer for music

# Function ready
func _ready():
	# Initialize the music player
	music_player = get_node("VibesPlayer")  # Adjust this path based on your scene hierarchy

	# Start playing the background music if not already playing
	if music_player:
		if not music_player.is_playing():  # Check if the music is already playing
			music_player.play()  # Start playing the music

	# Initialize AudioStreamPlayer reference and set the sound stream
	button_click_player = $ButtonClickPlayer
	button_click_player.stream = load("res://sounds/click.ogg")

	if $SubscribeLabel:
		$SubscribeLabel.connect("gui_input", Callable(self, "_on_SubscribeLabel_clicked"))

	if $DiscordLabel:
		$DiscordLabel.connect("gui_input", Callable(self, "_on_DiscordLabel_clicked"))

func _on_SettingsButton_pressed():
	_play_button_click_sound()  # Play the button click sound
	print("Settings Button Clicked!")  # Log button click to the console
	
	# Load and instance the SettingsPopup.tscn
	if settings_popup == null:  # Check if the popup is not created
		var packed_scene = preload("res://settingspopup.tscn")  # Preload the scene
		settings_popup = packed_scene.instantiate()  # Instantiate the scene
		get_tree().current_scene.add_child(settings_popup)  # Add to the current scene
		settings_popup.popup_centered()  # Show it centered on the screen
	else:
		if settings_popup.is_visible():
			settings_popup.hide()  # Hide the popup if it's visible
		else:
			settings_popup.popup_centered()  # Show it centered on the screen

# Function to play button click sound
func _play_button_click_sound():
	button_click_player.play()  # Play the button click sound


func _on_Button_pressed():
	_play_button_click_sound()  # Play the button click sound
	print("Credits Button Clicked!")  # Log button click to the console
	if credits_popup == null:  # Check if the popup is not created
		credits_popup = Popup.new()  # Create a new popup

		# Create a RichTextLabel for credits with clickable links
		var rich_text_label = RichTextLabel.new()  
		rich_text_label.bbcode_enabled = true  # Enable BBCode for clickable links
		rich_text_label.text = "Game by [url=https://youtube.com/@monkagaming420]MonkaGaming420YT[/url]/Anthony\n" + \
			"Song name at home page: [url=https://www.youtube.com/watch?v=x-ObUKegl6g]Vibes - David Renda[/url]\n" + \
			"Click sound effect: [url=https://freesound.org/people/Breviceps/sounds/448081]Tic Toc UI Click[/url]\n" + \
			"Simple Tic Tac Toe picture credits: [url=https://projectbook.code.brettchalupa.com/games/img/ttt.webp]https://projectbook.code.brettchalupa.com/games/img/ttt.webp[/url]\n" + \
			"Super Tic Tac Toe credits: [url=https://upload.wikimedia.org/wikipedia/commons/7/7d/Super_tic-tac-toe_rules_example.png]https://upload.wikimedia.org/wikipedia/commons/7/7d/Super_tic-tac-toe_rules_example.png[/url]\n"  # BBCode for clickable links

		# Set minimum size for the label
		rich_text_label.custom_minimum_size = Vector2(200, 100)  
		credits_popup.add_child(rich_text_label)  # Add the label to the popup
		
		# Connect the link click event to open the URL
		rich_text_label.connect("meta_clicked", Callable(self, "_on_link_clicked"))

		# Connect the close functionality
		credits_popup.connect("popup_hide", Callable(self, "_on_CreditsPopup_closed"))

		# Add the popup to the current scene
		get_tree().current_scene.add_child(credits_popup)  # Adding to the current scene

		# Position the popup in the center of the screen after it's been added to the tree
		credits_popup.popup_centered()  # Show it centered on the screen
	else:
		# If popup is already created, just show or hide it
		if credits_popup.is_visible():
			credits_popup.hide()  # Hide the popup if it's visible
		else:
			credits_popup.popup_centered()  # Show it centered on the screen

# Function to handle link clicks
func _on_link_clicked(meta: String):
	print("Clicked link: ", meta)  # Print the clicked link
	OS.shell_open(meta)  # Open the link in the default browser

func _on_PlayButton_pressed():
	print("Play Button sound trigger")
	_play_button_click_sound()  # Play the button click sound

	# Add a slight delay if necessary
	await get_tree().create_timer(0.15).timeout

	print("Play Button Pressed")
	get_tree().change_scene_to_file("res://ultimate_or_simple.tscn")

func _on_SaveButton_pressed():
	_play_button_click_sound()  # Play the button click sound for the save button

	# Save settings logic can be modified here if you still want to save other settings
	print("Settings Saved.")

func _on_DiscordLabel_clicked(event: InputEvent):
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
		print("Discord Label Clicked!")  # Print message when Discord label is clicked
		OS.shell_open("https://discord.gg/hX9JeZD7Rx")  # Open Discord in default browser

# Function to handle when the SubscribeLabel is clicked
func _on_SubscribeLabel_clicked(event: InputEvent):
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
		print("Subscribe Label Clicked!")  # Print message when Subscribe label is clicked
		OS.shell_open("https://www.youtube.com/@monkagaming420")  # Open YouTube channel in the default browser

I dont know if this has anything to do with it but SFXManager.gd

extends Node

# Function to mute/unmute SFX
func set_mute_state(is_muted: bool):
	var bus_index = AudioServer.get_bus_index("custombuslayout")  # Get the index of your custom bus
	if is_muted:
		AudioServer.set_bus_volume_db(bus_index, -80)  # Mute the bus
	else:
		AudioServer.set_bus_volume_db(bus_index, 0)     # Unmute the bus
	
	# Optional: Save the mute state to a config file
	var config = ConfigFile.new()
	config.set_value("audio", "sfx_muted", is_muted)
	config.save("user://settings.cfg")

	# Log the mute state change
	var mute_status = "muted" if is_muted else "unmuted"
	print("SFX is " + mute_status)

# Function to load mute state from config on startup
func load_mute_state():
	var config = ConfigFile.new()
	var err = config.load("user://settings.cfg")
	if err == OK:
		var is_muted = config.get_value("audio", "sfx_muted", false)  # Default to false (not muted)
		set_mute_state(is_muted)
	else:
		print("No settings file found, using default audio settings.")

func _ready():
	load_mute_state()  # Load the saved mute state when the game starts

Here is settingspopup SceneTree

image

UI.GD SceneTree

Here is all the Scripts if u need them, let me know if u want specific scripts.

image
image
Here are all the Scenes



Singleton/Autoloads

Audio Buses:
image

Sorry if this seems confusing, but, Let me know if u need any scripts or SceneTrees :slight_smile:

Nevermind, I solved it myself it was the command from

func initialize_controls():
	# load_mute_state()

	vibes_player = get_node("/root/Control/VibesPlayer")  # Adjust path if needed
	print("Vibes Player Status Before Initialization: ", vibes_player.volume_db)  # Debug volume level

	if vibes_player and not vibes_player.playing:
		vibes_player.play()  # Start music if it's not already playing
		print("Vibes Player Started Playing")  # Debug to confirm play start
	else:
		print("Vibes Player Already Playing")  # Confirm music is already playing

	print("Vibes Player Status After Initialization: ", vibes_player.volume_db)  # Confirm if volume changes

It was load_mute_state() so i disabled it

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.