I’m adding audio to my game; more specifically, ambient audio, so I’m using AudioStreamPlayers with Surround mix.
What I want to do is give the engine 7, maybe 8 vaguely sinister wind-like sounds, and let it randomly play one out of them based on a random chance roll once every 12 seconds (random chance is currently 1 in 5)
Problem: Currently, the code that does this is connected to the Level Node, because I don’t know how to get the autoloader to wait for a new scene to load and finish loading before it begins its sound shenanigans. I don’t like the fact that I’m attaching it to the level node.
Here’s the code, the script is named AmbientManager.gd:
extends Node2D
var ambient_nodes:Array[Node]
var randomizer:RandomNumberGenerator = RandomNumberGenerator.new()
var ambience_timer:Timer = Timer.new()
func _ready():
ambient_nodes = get_tree().get_nodes_in_group("Ambience")
add_child(ambience_timer)
ambience_timer.wait_time = 12.0
ambience_timer.one_shot = false
ambience_timer.timeout.connect(play_ambiance)
ambience_timer.start()
func play_ambiance() -> void:
if randomizer.randi_range(1, 5) == 5:
ambient_nodes[0].play()
Maybe your AmbientManager just needs to listen to the signal of when a new scene is loaded.
Also I am not quite sure what to make of your scene hierarchy because my mindset might be different.
Once the level is loaded, it should demand the music to play. Because you have the AmientManager as an autoload, it should be accessible everywhere in your code.
Also, by self.ready.emit(func(): AmbientManager.play_ambiance()), did you mean to use connect() instead?
Every node should have a ready signal that is published when all resources are loaded. We can make use of that to call the method of the AmbientManager. It may also be enough to write the AmbientManager.play_ambiance() directly into the _ready() method of the scene.
The SceneTree you described isn’t correct, my current setup is:
I see, thank you for the correction. So your AmbientManager is not actually its own Node but instead it’s the SceneScript (which is also alright). You can then disregard my statement above.
Due to the fact that your AmbientPlayers are direct children of the Scene, then your approach should be functional. The only downside is that the audio cuts abruptly if you want to change the scene. If your game is played purely in one scene, this shouldnt be an issue.
additionally, creating an autoload for your Audioplayer so it can be accessed by your scenes. Your level can then communicate with the audioplayers and the user interface menus which exit outside of your level.
Feel free to test things about and find a system that works out for you, there are many ways to achieve this. There may be even better systems than the one i propose.