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 whenever I start the game, the music I added works, but when I turn it down, its barely noticable, but when I click the PlayButton, and go back to home, the music works fine and I can turn it down and mute it, any ideas?
Here is a video to show what it’s doing
Here is the SceneTree for UI.tscn
VibesPlayer is my music player thingy
Here is some of my code to help
UI.gd (The script that contains the home screen)
extends Control
var credits_popup: Popup = null
var settings_popup: Popup = null
var button_click_player: AudioStreamPlayer = null # Reference to the AudioStreamPlayer
#function ready
func _ready():
# 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"))
# 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=yt link]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_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
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("my dsc link") # 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("my yt link") # Open YouTube channel in the default browser
func _on_SFXMuteButton_toggled(pressed: bool):
# Mute or unmute the SFX based on the button state
if pressed:
print("SFX Muted")
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), -60) # Mute SFX
else:
print("SFX Unmuted")
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), 0) # Unmute SFX
Here is settingspopup.gd (the script that contains the settings pop up and somewhat controls the music across the whole game)
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: VibesPlayer # Changed to specific type for better clarity
# Called when the node enters the scene tree for the first time.
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
# Set the size of the ColorRect
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
# Show the popup
popup()
# Adjust size flags
vbox_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
vbox_container.size_flags_vertical = Control.SIZE_EXPAND_FILL
# Get reference to VibesPlayer from the current scene or UI
vibes_player = get_tree().current_scene.get_node("VibesPlayer") # Adjust path as needed
if not vibes_player:
print("VibesPlayer not found in the current scene")
# Initialize slider and mute state
initialize_controls()
# Call the method to connect signals
_connect_signals()
# Function to initialize controls based on the current state of VibesPlayer
func initialize_controls():
if vibes_player:
volume_slider.value = (vibes_player.volume_db + 60) / 60 * 100 # Correctly map the volume
sfx_mute.set_pressed(volume_slider.value == 0) # Mute if volume is 0
else:
print("No valid VibesPlayer found.")
# Function to connect signals
func _connect_signals():
# Disconnect previous connections to avoid multiple connections
if volume_slider.is_connected("value_changed", Callable(self, "_on_Volume_Slider_value_changed")):
volume_slider.disconnect("value_changed", Callable(self, "_on_Volume_Slider_value_changed"))
volume_slider.connect("value_changed", Callable(self, "_on_Volume_Slider_value_changed"))
if sfx_mute.is_connected("toggled", Callable(self, "_on_SFXMute_toggled")):
sfx_mute.disconnect("toggled", Callable(self, "_on_SFXMute_toggled"))
sfx_mute.connect("toggled", Callable(self, "_on_SFXMute_toggled"))
# Function to handle volume slider value change
func _on_Volume_Slider_value_changed(value: float):
if vibes_player:
print("Volume slider changed to:", value) # Debugging
# Convert slider value to dB and adjust the volume of VibesPlayer
var volume_db = value_to_db(value)
vibes_player.set_volume_db(volume_db) # Use the set_volume_db function in VibesPlayer
# Function to handle SFX mute button state change
func _on_SFXMute_toggled(pressed: bool):
if vibes_player: # Use the member variable instead of redeclaring it
if pressed:
vibes_player.set_volume_db(-80) # Mute
volume_slider.value = 0 # Update slider position
else:
vibes_player.set_volume_db((volume_slider.value / 100.0) * 60 - 60) # Restore volume
# Function to convert slider value to dB
func value_to_db(value: float) -> float:
return (value / 100.0) * 60 - 60 # Scale from 0 to -60 dB
# Function to handle save button pressed
func _on_SaveButton_pressed():
# Add your save logic here
print("Save button pressed")
var volume_value = volume_slider.value
var is_muted = sfx_mute.is_pressed()
print("Volume:", volume_value)
print("SFX Mute:", is_muted)
# Function to handle close button pressed
func _on_CloseButton_pressed():
hide() # Hide the popup when closed
print("Popup closed")
Here is VibesPlayer.gd (the script for the music)
extends AudioStreamPlayer
class_name VibesPlayer
func _ready():
# Set the initial volume
set_volume(100.0) # Set initial volume to maximum (or any desired value)
# Delay starting playback to ensure everything is ready
await get_tree().create_timer(0.1).timeout # Wait for 0.1 seconds
play() # Start playing the audio
# Connect the 'finished' signal to handle when the audio finishes playing
self.connect("finished", Callable(self, "_on_finished"))
func set_volume(value: float):
volume_db = value_to_db(value)
func value_to_db(value: float) -> float:
return (value / 100.0) * 60 - 60 # Convert slider value to dB
# Signal handler for when the audio finishes
func _on_finished():
# Play the audio again at normal speed
play() # Play the audio again
Here is MusicPlayer.gd (The script that controls the music but is connected to the singleton in my project settings)
extends Node
# Preload the VibesPlayer script to ensure it's recognized
var VibesPlayerScript = preload("res://VibesPlayer.gd") # Ensure the path is correct
var vibes_player: VibesPlayer # Now it recognizes the class name
func _ready():
vibes_player = VibesPlayerScript.new() # Instantiate the VibesPlayer class
# Add the vibes_player to the current scene instead of the root
get_tree().current_scene.add_child(vibes_player) # Add to the current scene
vibes_player.stream = load("res://vibes.ogg") # Ensure this path is correct
# Call play deferred to ensure the node is inside the tree
vibes_player.call_deferred("play")
Let me know if you need any extra scripts or SceneTree’s to help with this, Thank you so much