Description
Motivation
Following up on a question posed during the "ecs-based audio" refactor in #8424 (comment) which I don't think was ever really addressed.
This begs the question: should
PlaybackMode::Once
even exist? Does it even make sense to retain audio-related components, if sound is no longer playing?
As well as this comment on PlaybackMode
:
bevy/crates/bevy_audio/src/audio.rs
Lines 76 to 79 in f67b17d
Motivated by a recent Discord discussion about "how to replay a sound."
What problem does this solve or what need does it fill?
PlaybackSettings
currently defaults to PlaybackMode::Once
, meaning the audio will play once, and then the audio entity and its components are left alone and not despawned or removed.
That sounds convenient at first. After the AudioSink
is created, it can be re-used, saving you the CPU cycles of spawning, despawning, and creating the sink. Or archetype-moves adding/removing components.
Unfortunately, it really can't be reused. Once the audio in the sink's queue is played, it is gone, and there is no way for a user to refill the sink and start playback again. The only way I know of to restart audio is to remove the AudioSink
component from the entity -- play_queued_audio_system
will create a new one. That trick doesn't work for playing a different sound with the same sink. See #11862.
So why does this mode exist, and why is the default behavior to leak audio entities into the world and never clean them up?
What solution would you like?
Make the default behavior PlaybackMode::Remove
, and add an internal system that cleans up "orphaned" entities when audio components are removed and the entity is otherwise "empty."
Leave PlaybackMode::Once
around in case it is useful to someone. Add docs explaining why it's sort of useless?
What alternative(s) have you considered?
-
Make the default behavior
PlaybackMode::Despawn
. This is might be what users want most often. LeaveOnce
in case it's useful to someone. -
Same, but remove
PlaybackMode::Once
. -
Keep current default behavior, remove the
TODO
comment. -
Add some sort of machinery for reusing a sink by refilling it or filling it with different audio.
I naively attempted to add
append
to theAudioSinkPlayback
trait, but it required making the trait generic, and it seemed like a mess. It's probably possible, but that route would lead to a pretty inconvenient API that seems counter to the "ecs-based audio." Using change detection onHandle<Source>
seems like it would be pretty funky too.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status