Repository navigation
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::Onceeven 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
| fn default() -> Self { | |
| // TODO: what should the default be: ONCE/DESPAWN/REMOVE? | |
| Self::ONCE | |
| } |
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. LeaveOncein case it's useful to someone. -
Same, but remove
PlaybackMode::Once. -
Keep current default behavior, remove the
TODOcomment. -
Add some sort of machinery for reusing a sink by refilling it or filling it with different audio.
I naively attempted to add
appendto theAudioSinkPlaybacktrait, 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
- StatusShow more project fieldsDone
Activity
rparrett commentedon Mar 7, 2024
I feel like exposing raw rodio types is probably a non-starter as a user-facing API, but I am definitely not a subject-matter expert.
SolarLiner commentedon Mar 12, 2024
Entity commands could fit here, I think. The command would either queue the audio onto the existing
Sinkif already existing, therefore reusing it, or create a newAudioSinkcomponent otherwise.Magnitus- commentedon Jun 5, 2024
Thanks for clarifying that for me. I was wondering if I could reuse an existing audio component that doesn't loop for some events (like button clicks) or if I should just re-recreate the component to play the sound each time the event occurs (which seems a little wasteful, hence my hesitation).
I guess it is the later then.
rparrett commentedon Dec 11, 2024
I don't think that I agree with the premise of this issue anymore. I am not sure that entities "magically" despawning themselves or components removing themselves make for great defaults in an "ECS-based API". This behavior is likely to be just as surprising to people.
I think that the lack of sink re-usability should be treated as a bug and possibly the documentation improved to reflect the current limitations if it doesn't seem like a fix is forthcoming.
Remove TODO and add docs about limitations of `PlaybackMode::Once` (#…
Remove TODO and add docs about limitations of `PlaybackMode::Once` (b…
Remove TODO and add docs about limitations of `PlaybackMode::Once` (b…