bevy_rapier icon indicating copy to clipboard operation
bevy_rapier copied to clipboard

False collision events fired when spawning sensors

Open james-j-obrien opened this issue 3 years ago • 1 comments

Simple repro created from the demo below:

use bevy::prelude::*;
use bevy_rapier2d::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
        .add_plugin(RapierDebugRenderPlugin::default())
        .add_startup_system(setup_graphics)
        .add_startup_system(setup_physics)
        .add_system(collisions)
        .add_system(spawn_sensor)
        .run();
}

fn setup_graphics(mut commands: Commands) {
    // Add a camera so we can see the debug-render.
    commands.spawn_bundle(Camera2dBundle::default());
}

fn setup_physics(mut commands: Commands, mut rapier: ResMut<RapierConfiguration>) {
    rapier.gravity = Vec2::ZERO;

    /* Create the rigid body. */
    commands
        .spawn()
        .insert(RigidBody::Dynamic)
        .insert(Collider::ball(10.0))
        .insert(ActiveEvents::COLLISION_EVENTS)
        .insert_bundle(TransformBundle::from(Transform::from_xyz(0., 0.0, 0.0)));
}

fn spawn_sensor(mut commands: Commands, keys: Res<Input<KeyCode>>) {
    /* Create the sensor. */
    if keys.pressed(KeyCode::Space) {
        commands
            .spawn()
            .insert(Sensor)
            .insert(Collider::ball(10.0))
            .insert_bundle(TransformBundle::from(Transform::from_xyz(0.0, -100.0, 0.0)));
    }
}

pub fn collisions(mut collision_events: EventReader<CollisionEvent>) {
    for collision_event in collision_events.iter() {
        match collision_event {
            CollisionEvent::Started(e1, e2, _flags) => {
                println!("Start: {:?}, {:?}", e1, e2);
            }
            CollisionEvent::Stopped(e1, e2, _flags) => {
                println!("Stop: {:?}, {:?}", e1, e2);
            }
        }
    }
}

Hold space to spawn sensors which will fire false collision events. Seems that when spawned the colliders remain at the origin for one frame. Perhaps a bug in init_colliders, I'm not too familiar with the codebase.

Edit: Found the bug in init_colliders, see linked PR

james-j-obrien avatar Aug 24 '22 18:08 james-j-obrien

~~Your patch seems to fixes my weird collision issue. When I spawn a bunch of entities with Transform and Collider (one of which is my player) my player collide all the spawned entities even though it doesn't appear to (and shouldn't) intersect them.~~

~~It also seems to introduce a new issue: an entity with Transform and Collider is now treated as living at (0.0, 1.0, 0.0) when I spawn it with a translation of (x, 0.0, z).~~

~~I can put up a branch if you'd like.~~

I've resolved my issue by adding a RigidBody component to each of the entities involved. Does your repro still happen when you add RigidBody::Fixed to the entity that has Sensor?

LightAndLight avatar Sep 26 '22 08:09 LightAndLight

I also encountered this problem and thought that I was doing something wrong. Since I needed a one-time check, I solved it by replacing the collider with intersections_with_shape.

KnstAnt avatar Nov 03 '22 22:11 KnstAnt