use avian2d::{parry::query::ClosestPoints, prelude::*}; use bevy::{prelude::*, transform::TransformSystem}; use bevy_synthizer::{Listener, Sound}; use crate::core::GlobalTransformExt; #[derive(Component, Default, Reflect, Clone, Copy, Debug)] #[reflect(Component)] pub struct Volumetric; fn update( mut commands: Commands, listener: Query<(&Collider, &GlobalTransform), With>, mut sounds: Query<(Entity, &Sound, &Parent, Option<&mut Transform>), With>, colliders: Query<(&Collider, &GlobalTransform)>, ) { if let Ok((listener_collider, listener_global_transform)) = listener.get_single() { for (sound_entity, sound, parent, sound_transform) in &mut sounds { if sound.paused { continue; } let Ok((sound_collider, sound_global_transform)) = colliders.get(**parent) else { continue; }; let closest = listener_global_transform.closest_points( listener_collider, sound_global_transform, sound_collider, ); if let ClosestPoints::WithinMargin(_p1, p2) = closest { if let Some(mut sound_transform) = sound_transform { sound_transform.translation.x = p2.x - sound_global_transform.translation().x; sound_transform.translation.y = p2.y - sound_global_transform.translation().y; } else { let sound_translation = Vec3::new( p2.x - sound_global_transform.translation().x, p2.y - sound_global_transform.translation().y, 0., ); commands .entity(sound_entity) .insert(TransformBundle::from_transform( Transform::from_translation(sound_translation), )); } } else if closest == ClosestPoints::Intersecting && sound_transform.is_some() { commands .entity(sound_entity) .remove::() .remove::(); } } } } 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); } }