use bevy::{prelude::*, transform::TransformSystem}; use bevy_rapier2d::{parry::query::ClosestPoints, prelude::*}; use bevy_synthizer::{Listener, Sound}; use crate::core::GlobalTransformExt; #[derive(Component, Default, Reflect, Clone, Copy, Debug)] #[reflect(Component)] pub struct Volumetric; fn update( listener: Query<(&Collider, &GlobalTransform), With>, mut sounds: Query<(&Sound, &Parent, &mut Transform), With>, colliders: Query<(&Collider, &GlobalTransform)>, ) { if let Ok((listener_collider, listener_global_transform)) = listener.get_single() { for (sound, parent, mut sound_transform) in &mut sounds { if sound.paused { continue; } if let Ok((sound_collider, sound_global_transform)) = colliders.get(**parent) { 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.); 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 { 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, mut removed: RemovedComponents, transforms: Query, With)>, ) { for entity in removed.read() { if transforms.get(entity).is_ok() { commands.entity(entity).insert(TransformBundle::default()); } } } pub struct VolumetricPlugin; impl Plugin for VolumetricPlugin { fn build(&self, app: &mut App) { app.register_type::() .add_systems( PostUpdate, update.before(TransformSystem::TransformPropagate), ) .add_systems(PostUpdate, removed); } }