Search code examples
game-developmentgodotgdscript

Having an audio issue in godot where audio plays when i dont want it to


I am a beginner coder. I'm trying to make a dialog box that plays audio when the text is being read out. I've got it to work well but I've ran into two issues.

The first (being the most important) is that whenever I start the level the sound plays without me completing the conditional (I honestly don't know the term for it). The second problem is that if I press ui_accept(enter) too fast, if i do it before the dialog is done, sometimes just randomly, the audio keeps playing even after the dialog is closed.

Code for dialog box

extends Control

var dialog = [
    'test1',
    'test2',
]
var dialog_index = 0
var finished = false
var test = false

func _ready():
    MusicController.dialogsfx.stop()
    load_dialog() 
    Global.DialogBox = self
    
func _exit_tree():
    Global.DialogBox = null


func _physics_process(delta):
    $"Ind".visible = finished
    if Input.is_action_just_pressed("ui_accept"):
        load_dialog()
    if test == true:
        if finished == false:
            MusicController.dialogsfx.play()
        if finished == true:
            MusicController.dialogsfx.stop()
    if Global.player.can_move:
        MusicController.dialogsfx.stop()

func load_dialog():
    if dialog_index < dialog.size():
        test = true
        finished = false
        $RichTextLabel.bbcode_text = dialog[dialog_index]
        $RichTextLabel.percent_visible = 0
        $Tween.interpolate_property(
            $RichTextLabel, "percent_visible",  0, 1, 1,
            Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
        )
        $Tween.start()
        
        
    else:
        Global.npc1.dialogsoundstop = true
        MusicController.dialogsfx.stop()
        Global.player.can_move = true
        Global.npc1.done = true
        test = false
        print("test3")
        print("test4")

        queue_free()
        test = false
        
    dialog_index += 1
    
func _on_Tween_tween_completed(object, key):
    finished = true

Code for MusicController

extends Node

var menu_music = load("res://mainmenutheme.wav")
var dialog_sfx = load("res://Sounds/dialogsound.wav")
onready var dialogsfx = $dialogsfx

func _ready():
    $dialogsfx.stream = dialog_sfx

func play_music():
    $Music.stream = menu_music
    $Music.play()


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#   pass

Solution

  • I think you can do this entirely on load_dialog. When there are text lines start the audio:

    func load_dialog():
        if dialog_index < dialog.size():
            # … some code …
            MusicController.dialogsfx.play()
        else:
            # … some code …
            
        dialog_index += 1
    

    You can also check if it is already playing, and if it is, don't play it again:

    func load_dialog():
        if dialog_index < dialog.size():
            # … some code …
            if not MusicController.dialogsfx.playing:
                MusicController.dialogsfx.play()
        else:
            # … some code …
            
        dialog_index += 1
    

    And when there no longer are, stop it:

    func load_dialog():
        if dialog_index < dialog.size():
            # … some code …
            if not MusicController.dialogsfx.playing:
                MusicController.dialogsfx.play()
        else:
            # … some code …
            MusicController.dialogsfx.stop()
            
        dialog_index += 1
    

    I don't know if you want the audio to stop when the text finished revealing (i.e. when the tween completed). If you do, you can add that in _on_Tween_tween_completed:

    func _on_Tween_tween_completed(object, key):
        # … some code …
        MusicController.dialogsfx.stop()
    

    By the way, you say that the sound plays when you load the level. It could be that the AudioStreamPlayer has autoplay set to true.