AudioStreamPlayer refuses to play when created and added through code

Godot Version

v4.4.1.stable.mono.official [49a5bc7b6]

Question

I have a variable that I export which is expected to be an OGG stream.

[Export] public AudioStreamOggVorbis PickupSound { get; set; }

Inside my _Ready() function I do the following:

if (PickupSound is not null)
{
	_audioPlayer = new AudioStreamPlayer();
	AddChild(_audioPlayer);
	_audioPlayer.SetStream(PickupSound);
}

Then, later on, when the player interacts with this object, I want to play the sound, like this:

if (PickupSound is not null)
{
	_audioPlayer.Play();
}

HOWEVER, no matter what I do, no sound will ever be played like this, and I get no exceptions or warnings at all. Is there a reason why?

So far I tried _audioPlayer.Stream = PickupSound as well but it gave me the same results, I also tried to set the stream BEFORE adding the _audioPlayer as a child, but still nothing.

Is this expected behaviour? What’s happening?

Are you assigning the PickupSound in the inspector? Does the code enter the ifs? Does the AudioStreamPlayer get added to the scene tree? (you can check that in the Remote tab in the Scene dock while the game is running)

I do assign it, and I stepped through the code to make sure nothing is null and everything gets executed. That’s why I’m confused, as no exception or warning is thrown and everything SHOULD work.

I don’t have C# setup but this gdscript code works just fine:

extends Node

@export var stream:AudioStreamOggVorbis

var player: AudioStreamPlayer


func _ready() -> void:
	if not stream == null:
		player = AudioStreamPlayer.new()
		add_child(player)
		player.stream = stream


func _process(delta: float) -> void:
	if Input.is_action_just_pressed(&"ui_accept"):
		if not stream == null:
			player.play()

Does other audio work?

All other audio works just fine, and if I instead create the audio node in my scene, add the stream to it and reference it in code to call the Play() function on it it works fine. It always works if I already have the node in my PackedScene when the game runs, but it never works when I create the AudioStreamPlayer node during runtime.

why do you want to generate an audiostream player through code?

you can just add an audiostream player in the scene

and in the code you can change the stream manually

this is how it works in GDScript(maybe it can give you an idea of how it works)

extends AudioStreamPlayer

const start_music = preload("res://assets/music/start.mp3")
const boss_music = preload("res://assets/music/bossfight.mp3")
const first_steps= preload("res://assets/music/first steps.mp3")

var song = 1

@onready var player: AudiostreamPlayer = $AudioStreamPlayer

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	pass # Replace with function body.


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

func play_music(music : AudioStream, volume = 0):
	if player.stream == music:
		return
		
	player.stream = music
	player.volume_db = volume
	player.play()
	
func play_music_level():
	if song == 1:
		play_music(start_music)
		player.volume_db = 0
	if song == 2:
		play_music(boss_music)
		player.volume_db = 0
	if song == 3:
		play_music(first_steps)
		player.volume_db = -14
func change_music():
	if song == 1:
		song = 2
	if song == 2:
		song = 1

Because there are some parts in my game where entire scenes are generated using code, and this should be perfectly normal behaviour that godot handles.

I’ll try to create a MRP as I feel like it’s a bug.

did you preloaded that sfx

like:

const start_music = preload("res://assets/music/start.mp3")

because if you don’t do that, it will not work

As you can see in my original post, it’s an AudioStreamOggVorbis, which means it requires no preloading, as it’s the stream that I directly assign inside the inspector for that specific node.

do you get an error or warn while playing, it can help me alot that way i can fix your problem, im not a C# user but i was a java user(is similar to C#) and i learned a bit of C# a time ago sooo, it will be possible to fix

As mentioned before, I get no error messages or any exceptions which is what bothers me, otherwise I would know what’s wrong.
Calling the function works, I stepped through the code line by line and everything was correctly created, nothing was missing, yet no audio is being played.

Thank you for the help so far, I’ll likely try and re-create this in an empty project to track down the cause.

don’t do it pls, i have an idea, sorry because of frustrating you, but can i get your project to understand it better? send me the game folder and i will search the issue :slight_smile:

That I cannot do, the game is under NDA.

im not a C# user soo it would be hard to understand(even tho i know java) look at your files, nodes and scenes if there is something that causes that

wait, does the function get called?

like, if the player collects something that the function/void gets called

Yep, the function gets called correctly, already stepped through the code line by line.

well then, just check all scripts, nodes, scenes and other files

Weird, I tested this C# code:

using Godot;

public partial class TestAudioStreamPlayerExport : Node
{
	[Export]
	public AudioStreamOggVorbis stream;

	private AudioStreamPlayer player;

	public override void _Ready()
	{


	}

	public override void _Process(double delta)
	{
		if (stream is not null)
		{
			if (Input.IsActionJustPressed("ui_up") && player is null)
			{
				if (player is null)
				{
					player = new AudioStreamPlayer();
					AddChild(player);
					player.Stream = stream;
				}
				player?.Play();
			}
		}
	}
}

And it works just fine:

1 Like

Yea I can’t reproduce it in a clean project either so I’ll start deleting stuff and see what causes it. Thank you!