Add experimental plugin for sounds that occupy a region, and should play at the nearest point on the collider.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Nolan Darilek 2022-08-23 09:49:14 -05:00
parent 5ba4b5272c
commit 07e745c3fc
2 changed files with 89 additions and 1 deletions

View File

@ -6,9 +6,11 @@ use crate::core::CoreConfig;
pub mod footstep; pub mod footstep;
pub mod icon; pub mod icon;
pub mod volumetric;
pub use footstep::Footstep; pub use footstep::Footstep;
pub use icon::SoundIcon; pub use icon::SoundIcon;
pub use volumetric::Volumetric;
/*fn scale_sounds(config: Res<CoreConfig>, mut sounds: Query<&mut Sound>) { /*fn scale_sounds(config: Res<CoreConfig>, mut sounds: Query<&mut Sound>) {
let pixels_per_unit = config.pixels_per_unit as f32; let pixels_per_unit = config.pixels_per_unit as f32;
@ -40,7 +42,8 @@ where
.unwrap(); .unwrap();
}*/ }*/
app.add_plugin(footstep::FootstepPlugin) app.add_plugin(footstep::FootstepPlugin)
.add_plugin(icon::SoundIconPlugin::<S>::default()); .add_plugin(icon::SoundIconPlugin::<S>::default())
.add_plugin(volumetric::VolumetricPlugin);
// .add_system(scale_sounds); // .add_system(scale_sounds);
} }
} }

85
src/sound/volumetric.rs Normal file
View File

@ -0,0 +1,85 @@
use bevy::{prelude::*, transform::TransformSystem};
use bevy_rapier2d::{parry::query::ClosestPoints, prelude::*};
use bevy_synthizer::{Listener, Sound};
use crate::{commands::RunIfExistsExt, core::GlobalTransformExt};
#[derive(Component, Clone, Copy, Debug)]
pub struct Volumetric;
fn update(
mut commands: Commands,
listener: Query<(&Collider, &GlobalTransform), With<Listener>>,
mut sounds: Query<
(
Entity,
Option<&Collider>,
Option<&Parent>,
&mut Transform,
&GlobalTransform,
),
With<Volumetric>,
>,
colliders: Query<&Collider>,
) {
if let Ok((listener_collider, listener_global_transform)) = listener.get_single() {
for (sound_entity, sound_collider, parent, mut sound_transform, sound_global_transform) in
&mut sounds
{
let sound_collider = if sound_collider.is_some() {
sound_collider
} else if let Some(parent) = parent {
colliders.get(**parent).ok()
} else {
None
};
if let Some(sound_collider) = sound_collider {
let closest = listener_global_transform.closest_points(
listener_collider,
sound_global_transform,
sound_collider,
);
if let ClosestPoints::WithinMargin(_p1, p2) = closest {
let p2 = Vec3::new(p2.x, p2.y, 0.);
if p2.distance(sound_global_transform.translation()) >= 1. {
sound_transform.translation.x =
p2.x - sound_global_transform.translation().x;
sound_transform.translation.y =
p2.y - sound_global_transform.translation().y;
}
} else if closest == ClosestPoints::Intersecting {
if sound_global_transform
.translation()
.distance(listener_global_transform.translation())
>= 1.
{
sound_transform.translation.x = listener_global_transform.translation().x
- sound_global_transform.translation().x;
sound_transform.translation.y = listener_global_transform.translation().y
- sound_global_transform.translation().y;
}
}
}
}
}
}
fn removed(mut commands: Commands, removed: RemovedComponents<Volumetric>) {
for entity in removed.iter() {
commands.run_if_exists(entity, |mut entity| {
entity.insert_bundle(TransformBundle::default());
});
}
}
pub struct VolumetricPlugin;
impl Plugin for VolumetricPlugin {
fn build(&self, app: &mut App) {
app.add_system_to_stage(
CoreStage::PostUpdate,
update.before(TransformSystem::TransformPropagate),
)
.add_system_to_stage(CoreStage::PostUpdate, removed);
}
}