godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.09k stars 21.18k forks source link

AudioStreamPlayer starting with window before game is ready #81549

Open Cigam-HFden opened 1 year ago

Cigam-HFden commented 1 year ago

Godot version

v4.1.1.stable.official [bd6af8e0e]

System information

Godot v4.1.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 Ti Laptop GPU (NVIDIA; 31.0.15.3713) - 12th Gen Intel(R) Core(TM) i9-12900H (20 Threads)

Issue description

Audio starts before the game is ready. In a movie project I am working on I needed to test timing of camera movements to the music. I wound up having to just do the movie maker exports since that would line up perfectly. However just running the game the music is offset. In the main script I have:

func _ready():
#   await get_tree().create_timer(0).timeout
    $music.play()

Doing only the music play is the same as the autoplay on the object itself, but to get it to line up close to when the game starts I had to add a timer of 0 seconds. That does not get it exact though it is slightly off just depending on how long it takes the game to load.

In my case I have a fairly detailed terrain shader that I copied, and modified. it works only ok, but because of the subdivisions takes a fair amount of time to load the game. In my attached project I removed the blender and object files associated with my project, and just left the camera, lights, terrain, etc. so that you could get an idea of what it was.

Steps to reproduce

Have an AudioStreamPlayer or AudioStreamPlayer3D in the scene (example has both, one in main scene and one in ship scene respectively). When running the game it will load those before the game is ready. making the script tell it to load after a timer of 0 gets close, but it would be nice if there was an option or settings to make the audio only start when the game is loaded.

Minimal reproduction project

Apologies for the 21 MB example project, I left in the 2 audio files I was using. The music is only 3 MB, but the spaceship sound is 18 MB. Both are from pixabay.

My Project: MVP music starts before game.zip

MJacred commented 1 year ago

That sounds like a tree order misunderstanding, please see https://kidscancode.org/godot_recipes/4.x/basics/tree_ready_order/index.html

Cigam-HFden commented 1 year ago

If I put the music at the top of the tree or the bottom the issue is the same. The music starts with the window appearing, not when the game is fully loaded.

Cigam-HFden commented 1 year ago

With godot 4.2 beta 4 it still has the issue.

MJacred commented 10 months ago

You play the music in _ready(): This means the music starts playing once the Node is ready to be used. This is mainly for initializing things. See documentation: https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-private-method-ready and https://docs.godotengine.org/en/stable/tutorials/scripting/scene_tree.html#becoming-active-by-entering-the-scene-tree.

And please note: autoplay in your audio player will start playing even before _ready(). It will start playing as soon as it enters the scene tree.

What you want is to know when your terrain and everything finished rendering!

This works:

# in main.gd

func _ready():
    RenderingServer.connect("frame_post_draw", play_music)

func play_music():
    RenderingServer.disconnect("frame_post_draw", play_music)
    $music.play()
Cigam-HFden commented 10 months ago

@MJacred Thank you, that makes sense and seems to solve the issue. I will use that connect method to make certain things start when the game is ready. Cheers!