Thomas O'Dell
Thomas O'Dell

Reputation: 554

bevy_rapier external impulse sometimes doesn't work

I'm writing a simple 2d game in Bevy, using bevy_rapier (This problem occurs under Bevy 0.14 and 0.15, with bevy_rapier 0.27 and 0.28). In my game, the player receives a bounce after hitting the ground, if he/she has lives left.

I set the player to be RigidBody::Dynamic, and add an ExternalImpulse component:


        RigidBody::Dynamic,
        GravityScale(0.1),
        ExternalImpulse {
            impulse: Vec2::ZERO,
            torque_impulse: 0.,
        },
        ExternalForce {
            force: Vec2::ZERO,
            torque: 0.,
        },

If the player presses the spacebar, I use external impulse to push the player up. This always works:

fn push_upward_on_keypress(
    input: Res<ButtonInput<KeyCode>>,
    mut ext_impulses: Query<&mut ExternalImpulse, With<Player>>,
) {
    let Ok(mut impulse) = ext_impulses.get_single_mut() else {
        return;
    };

    if input.just_pressed(KeyCode::Space) {
        println!("Space pressed.");
        impulse.impulse = UPWARD_IMPULSE;
    }
}

When the player hits the ground the collision generates a "Kill" event, which I process using the event reader. If the player has lives left, I push the player upward. This code works sometimes but stops working at all if I add any more systems to the code (the print statement is still executed):

fn handle_kill_event(
    mut lives_query: Query<(&mut Lives, &mut ExternalImpulse), With<Player>>,
    mut player_kill_events: EventReader<PlayerKillEvent>,
    mut player_die_events: EventWriter<PlayerDieEvent>,
) {
    let Ok((mut lives, mut impulse)) = lives_query.get_single_mut() else {
        return;
    };

    for _player_kill_event in player_kill_events.read() {
        println!("Player got kill event!");
        if lives.0 > 0 {
            lives.0 -= 1;
        }
        println!(" - number of lives is now {:?}", lives.0);
        if lives.0 > 0 {
            // TODO: this doesn't seem to be working
            impulse.impulse = UPWARD_IMPULSE;
            println!("Impulse set to {:?}", impulse.impulse);
        } else {
            // Die!
            player_die_events.send(PlayerDieEvent);
        }
    }
}

No other place in the code plays with ExternalImpulse.

How can I get the upward thrust to work consistently?

Upvotes: 1

Views: 33

Answers (0)

Related Questions