SpatialListener now requires a Transform (#19357)

I noticed that the `SpatialListener` asks to have a `Transform`
attached. It seemed weird that we didnt just use a require macro, so i
went ahead and did that
I also tweaked the system that plays audio to use a `&GlobalTransform`
instead of an `Option<&GlobalTransform>`
This commit is contained in:
Wuketuke 2025-07-07 21:48:57 +02:00 committed by GitHub
parent 3ad7a75781
commit 4865c538b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 26 deletions

View File

@ -3,6 +3,7 @@ use bevy_asset::{Asset, Handle};
use bevy_ecs::prelude::*;
use bevy_math::Vec3;
use bevy_reflect::prelude::*;
use bevy_transform::components::Transform;
/// The way Bevy manages the sound playback.
#[derive(Debug, Clone, Copy, Reflect)]
@ -10,10 +11,10 @@ use bevy_reflect::prelude::*;
pub enum PlaybackMode {
/// Play the sound once. Do nothing when it ends.
///
/// Note: It is not possible to reuse an `AudioPlayer` after it has finished playing and
/// the underlying `AudioSink` or `SpatialAudioSink` has been drained.
/// Note: It is not possible to reuse an [`AudioPlayer`] after it has finished playing and
/// the underlying [`AudioSink`](crate::AudioSink) or [`SpatialAudioSink`](crate::SpatialAudioSink) has been drained.
///
/// To replay a sound, the audio components provided by `AudioPlayer` must be removed and
/// To replay a sound, the audio components provided by [`AudioPlayer`] must be removed and
/// added again.
Once,
/// Repeat the sound forever.
@ -27,7 +28,7 @@ pub enum PlaybackMode {
/// Initial settings to be used when audio starts playing.
///
/// If you would like to control the audio while it is playing, query for the
/// [`AudioSink`][crate::AudioSink] or [`SpatialAudioSink`][crate::SpatialAudioSink]
/// [`AudioSink`](crate::AudioSink) or [`SpatialAudioSink`](crate::SpatialAudioSink)
/// components. Changes to this component will *not* be applied to already-playing audio.
#[derive(Component, Clone, Copy, Debug, Reflect)]
#[reflect(Clone, Default, Component, Debug)]
@ -78,10 +79,10 @@ impl Default for PlaybackSettings {
impl PlaybackSettings {
/// Will play the associated audio source once.
///
/// Note: It is not possible to reuse an `AudioPlayer` after it has finished playing and
/// the underlying `AudioSink` or `SpatialAudioSink` has been drained.
/// Note: It is not possible to reuse an [`AudioPlayer`] after it has finished playing and
/// the underlying [`AudioSink`](crate::AudioSink) or [`SpatialAudioSink`](crate::SpatialAudioSink) has been drained.
///
/// To replay a sound, the audio components provided by `AudioPlayer` must be removed and
/// To replay a sound, the audio components provided by [`AudioPlayer`] must be removed and
/// added again.
pub const ONCE: PlaybackSettings = PlaybackSettings {
mode: PlaybackMode::Once,
@ -164,14 +165,15 @@ impl PlaybackSettings {
/// Settings for the listener for spatial audio sources.
///
/// This must be accompanied by `Transform` and `GlobalTransform`.
/// Only one entity with a `SpatialListener` should be present at any given time.
/// This is accompanied by [`Transform`] and [`GlobalTransform`](bevy_transform::prelude::GlobalTransform).
/// Only one entity with a [`SpatialListener`] should be present at any given time.
#[derive(Component, Clone, Debug, Reflect)]
#[require(Transform)]
#[reflect(Clone, Default, Component, Debug)]
pub struct SpatialListener {
/// Left ear position relative to the `GlobalTransform`.
/// Left ear position relative to the [`GlobalTransform`](bevy_transform::prelude::GlobalTransform).
pub left_ear_offset: Vec3,
/// Right ear position relative to the `GlobalTransform`.
/// Right ear position relative to the [`GlobalTransform`](bevy_transform::prelude::GlobalTransform).
pub right_ear_offset: Vec3,
}
@ -182,7 +184,7 @@ impl Default for SpatialListener {
}
impl SpatialListener {
/// Creates a new `SpatialListener` component.
/// Creates a new [`SpatialListener`] component.
///
/// `gap` is the distance between the left and right "ears" of the listener. Ears are
/// positioned on the x axis.
@ -203,12 +205,12 @@ impl SpatialListener {
pub struct SpatialScale(pub Vec3);
impl SpatialScale {
/// Create a new `SpatialScale` with the same value for all 3 dimensions.
/// Create a new [`SpatialScale`] with the same value for all 3 dimensions.
pub const fn new(scale: f32) -> Self {
Self(Vec3::splat(scale))
}
/// Create a new `SpatialScale` with the same value for `x` and `y`, and `0.0`
/// Create a new [`SpatialScale`] with the same value for `x` and `y`, and `0.0`
/// for `z`.
pub const fn new_2d(scale: f32) -> Self {
Self(Vec3::new(scale, scale, 0.0))
@ -238,11 +240,11 @@ pub struct DefaultSpatialScale(pub SpatialScale);
/// If the handle refers to an unavailable asset (such as if it has not finished loading yet),
/// the audio will not begin playing immediately. The audio will play when the asset is ready.
///
/// When Bevy begins the audio playback, an [`AudioSink`][crate::AudioSink] component will be
/// When Bevy begins the audio playback, an [`AudioSink`](crate::AudioSink) component will be
/// added to the entity. You can use that component to control the audio settings during playback.
///
/// Playback can be configured using the [`PlaybackSettings`] component. Note that changes to the
/// `PlaybackSettings` component will *not* affect already-playing audio.
/// [`PlaybackSettings`] component will *not* affect already-playing audio.
#[derive(Component, Reflect)]
#[reflect(Component, Clone)]
#[require(PlaybackSettings)]

View File

@ -103,7 +103,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
Entity,
&AudioPlayer<Source>,
&PlaybackSettings,
Option<&GlobalTransform>,
&GlobalTransform,
),
(Without<AudioSink>, Without<SpatialAudioSink>),
>,
@ -118,7 +118,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
return;
};
for (entity, source_handle, settings, maybe_emitter_transform) in &query_nonplaying {
for (entity, source_handle, settings, emitter_transform) in &query_nonplaying {
let Some(audio_source) = audio_sources.get(&source_handle.0) else {
continue;
};
@ -136,14 +136,7 @@ pub(crate) fn play_queued_audio_system<Source: Asset + Decodable>(
}
let scale = settings.spatial_scale.unwrap_or(default_spatial_scale.0).0;
let emitter_translation = if let Some(emitter_transform) = maybe_emitter_transform {
(emitter_transform.translation() * scale).into()
} else {
warn!("Spatial AudioPlayer with no GlobalTransform component. Using zero.");
Vec3::ZERO.into()
};
let emitter_translation = (emitter_transform.translation() * scale).into();
let sink = match SpatialSink::try_new(
stream_handle,
emitter_translation,