feat: Added detect_colliders system

- Fixed colliders filtering in check_for_collisions
- Fixed group masks in tests
- Test collider_detects_different_groups now passes
This commit is contained in:
Alexey 2026-02-15 14:15:00 +03:00
commit 8f667f08c6
2 changed files with 21 additions and 11 deletions

View file

@ -105,7 +105,6 @@ impl Collider {
/// Returns true if any of self shapes intersect other's shapes, respecting groups.
/// Wrapper around [intersects_unchecked](Self::intersects_unchecked)
pub fn intersects(&self, other: &Collider) -> bool {
println!("groups: {}", self.check_mask & other.mask );
if self.check_mask & other.mask == 0 {
return false;
}
@ -139,7 +138,7 @@ pub struct UpdateShapes;
/// Update collider shapes to match new [`Transform`]
pub fn update_collider_shapes(
mut commands: Commands,
colliders: Query<(&mut Collider, &Transform, Entity), With<UpdateShapes>>,
colliders: Query<(&mut Collider, &Transform, Entity), Added<UpdateShapes>>,
) {
for (mut collider, transform, entity) in colliders {
collider.update_shapes_position(&transform.translation.xy());
@ -147,6 +146,16 @@ pub fn update_collider_shapes(
}
}
/// Detect new colliders and automatically insert [`UpdateShapes`]
pub fn detect_colliders(
mut commands: Commands,
query: Query<Entity, Added<Collider>>,
) {
for entity in query {
commands.entity(entity).insert(UpdateShapes);
}
}
#[derive(EntityEvent, Debug)]
/// Emitted when colliders intersect in [`check_for_collisions`] system
pub struct CollisionEvent {
@ -156,21 +165,22 @@ pub struct CollisionEvent {
pub detected: Entity,
}
fn collider_filter(checker: &&Collider, checkable: &&Collider) -> bool {
checker != checkable && checker.check_mask != 0
}
/// Check each [`Collider`] for collisions with another colliders.
/// Triggers [`CollisionEvent`] on collider intersection
pub fn check_for_collisions(
mut commands: Commands,
colliders: Query<(&Collider, Entity)>,
) {
let mut visited_colliders: Vec<&Collider> = Vec::new();
for (collider, entity) in colliders.iter() {
for (other_collider, other_entity) in colliders.iter().filter(|(c, _)| !visited_colliders.contains(c)) {
for (other_collider, other_entity) in colliders.iter().filter(|(c, _)| collider_filter(&collider, c)) {
if collider.intersects(other_collider) {
commands.trigger(CollisionEvent { entity, detected: other_entity });
}
}
visited_colliders.push(collider);
println!("{visited_colliders:?}");
}
}
@ -179,6 +189,6 @@ pub struct CollisionPlugin;
impl Plugin for CollisionPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PostUpdate, (update_collider_shapes, check_for_collisions).chain());
app.add_systems(PostUpdate, (detect_colliders, update_collider_shapes, check_for_collisions).chain());
}
}