diff --git a/src/components/audio_listener.rs b/src/components/audio_listener.rs index e599684..f384989 100644 --- a/src/components/audio_listener.rs +++ b/src/components/audio_listener.rs @@ -1,34 +1,39 @@ +use bevy::math::Vec3; use bevy::prelude::{Component, GlobalTransform, Query, Res, With}; use crate::attributes_3d::attributes3d; use crate::components::velocity::Velocity; use crate::fmod_studio::FmodStudio; +/// See the [`Velocity`] component for information on enabling the Doppler effect. #[derive(Component, Default)] pub struct AudioListener; impl AudioListener { pub(crate) fn update_3d_attributes( - query: Query<(&Velocity, &GlobalTransform), With>, + query: Query<(&GlobalTransform, Option<&Velocity>), With>, studio: Res, ) { - match query.get_single() { - Ok((velocity, transform)) => { - studio - .0 - .set_listener_attributes( - 0, - attributes3d( - transform.translation(), - velocity.current_velocity, - transform.forward(), - transform.up(), - ), - None, - ) - .unwrap(); + if let Ok((transform, vel_component)) = query.get_single() { + let mut velocity = Vec3::ZERO; + + if let Some(vel_component) = vel_component { + velocity = vel_component.current_velocity; } - _ => {} + + studio + .0 + .set_listener_attributes( + 0, + attributes3d( + transform.translation(), + velocity, + transform.forward(), + transform.up(), + ), + None, + ) + .unwrap(); } } } diff --git a/src/components/audio_source.rs b/src/components/audio_source.rs index 22346cc..6ac0472 100644 --- a/src/components/audio_source.rs +++ b/src/components/audio_source.rs @@ -1,3 +1,4 @@ +use bevy::math::Vec3; use bevy::prelude::{AudioSinkPlayback, Component, GlobalTransform, Query}; use libfmod::StopMode::Immediate; use libfmod::{EventDescription, EventInstance, StopMode}; @@ -5,6 +6,7 @@ use libfmod::{EventDescription, EventInstance, StopMode}; use crate::attributes_3d::attributes3d; use crate::components::velocity::Velocity; +/// See the [`Velocity`] component for information on enabling the Doppler effect. #[derive(Component)] pub struct AudioSource { pub event_instance: EventInstance, @@ -18,16 +20,22 @@ impl AudioSource { } pub(crate) fn update_3d_attributes( - mut query: Query<(&AudioSource, &Velocity, &GlobalTransform)>, + mut query: Query<(&AudioSource, &GlobalTransform, Option<&Velocity>)>, ) { query .iter_mut() - .for_each(|(audio_source, velocity, transform)| { + .for_each(|(audio_source, transform, vel_component)| { + let mut velocity = Vec3::ZERO; + + if let Some(vel_component) = vel_component { + velocity = vel_component.current_velocity; + } + audio_source .event_instance .set_3d_attributes(attributes3d( transform.translation(), - velocity.current_velocity, + velocity, transform.forward(), transform.up(), )) diff --git a/src/components/bundles.rs b/src/components/bundles.rs index 663ea53..55c8ce4 100644 --- a/src/components/bundles.rs +++ b/src/components/bundles.rs @@ -19,19 +19,9 @@ impl SpatialAudioBundle { } } -#[derive(Bundle)] +#[derive(Bundle, Default)] pub struct SpatialListenerBundle { audio_listener: AudioListener, velocity: Velocity, transform: Transform, } - -impl Default for SpatialListenerBundle { - fn default() -> Self { - SpatialListenerBundle { - audio_listener: AudioListener::default(), - velocity: Velocity::default(), - transform: Transform::default(), - } - } -} diff --git a/src/components/velocity.rs b/src/components/velocity.rs index 677bedc..ec0614f 100644 --- a/src/components/velocity.rs +++ b/src/components/velocity.rs @@ -2,6 +2,11 @@ use bevy::app::{App, Plugin, Update}; use bevy::math::Vec3; use bevy::prelude::{Component, FixedTime, GlobalTransform, Query, Res}; +/// Automatic velocity updates for [`AudioListener`] and [`AudioSource`] +/// +/// Make sure to add this component to your listener and source entities in order +/// to enable the Doppler effect. The recommended way to do this is to use the [`SpatialAudioBundle`] +/// and [`SpatialListenerBundle`]. #[derive(Component, Default)] pub struct Velocity { last_position: Vec3,