diff --git a/CHANGELOG.md b/CHANGELOG.md index d82f99d..ad9901e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Changelog -- update Kira to 0.9 - - removed `playback_region` from `SoundSettings` +- Update Kira to 0.9 + - Removed `playback_region` from `SoundSettings` - Add `android_shared_stdcxx` feature for Android Builds -- fix spatial audio when position of receiver and emitter are the same ([#135](https://github.com/NiklasEi/bevy_kira_audio/issues/135)) -- add `SpatialRadius` to control spatial audio distance range per entity -- rename `SpatialAudio` to `GlobalSpatialRadius` and rename it's field `max_distance` to `radius` +- Fix spatial audio when position of receiver and emitter are the same ([#135](https://github.com/NiklasEi/bevy_kira_audio/issues/135)) +- Add `SpatialRadius` to control spatial audio distance range per entity +- Rename `SpatialAudio` to `GlobalSpatialRadius` and rename its field `max_distance` to `radius` +- Add `SpatialDampingCurve` component to control the damping of spatial audio over distance using Bevy easing functions ## v0.21.0 - 30.11.2024 - Update to Bevy `0.15` diff --git a/src/spatial.rs b/src/spatial.rs index afe41f5..245f68d 100644 --- a/src/spatial.rs +++ b/src/spatial.rs @@ -8,7 +8,8 @@ use bevy::ecs::{ schedule::IntoSystemConfigs, system::{Query, Resource}, }; -use bevy::math::Vec3; +use bevy::math::{Curve, Vec3}; +use bevy::prelude::{EaseFunction, EasingCurve}; use bevy::transform::components::{GlobalTransform, Transform}; use std::f32::consts::PI; @@ -36,7 +37,7 @@ impl Plugin for SpatialAudioPlugin { /// Add [`Handle`]s to control their pan and volume based on emitter /// and receiver positions. #[derive(Component)] -#[require(Transform)] +#[require(Transform, SpatialDampingCurve)] pub struct SpatialAudioEmitter { /// Audio instances that are played by this emitter /// @@ -77,23 +78,35 @@ pub struct SpatialRadius { pub radius: f32, } +#[derive(Component)] +struct SpatialDampingCurve(EaseFunction); + +impl Default for SpatialDampingCurve { + fn default() -> Self { + SpatialDampingCurve(EaseFunction::Linear) + } +} + fn run_spatial_audio( spatial_audio: Res, receiver: Query<&GlobalTransform, With>, emitters: Query<( &GlobalTransform, &SpatialAudioEmitter, + &SpatialDampingCurve, Option<&SpatialRadius>, )>, mut audio_instances: ResMut>, ) { if let Ok(receiver_transform) = receiver.get_single() { - for (emitter_transform, emitter, range) in emitters.iter() { + for (emitter_transform, emitter, damping_curve, range) in emitters.iter() { let sound_path = emitter_transform.translation() - receiver_transform.translation(); - let volume = (1. - - sound_path.length() / range.map_or(spatial_audio.radius, |r| r.radius)) - .clamp(0., 1.) - .powi(2); + let progress = (sound_path.length() / range.map_or(spatial_audio.radius, |r| r.radius)) + .clamp(0., 1.); + let volume: f32 = 1. + - EasingCurve::new(0., 1., damping_curve.0) + .sample_unchecked(progress) + .clamp(0., 1.); let right_ear_angle = if sound_path == Vec3::ZERO { PI / 2.