[bevy] Elegant way to avoid same code in queries?

Hi,

I practice bevy.
Is there a elegant way to have only one common code for two components when using queries ?
I was looking the Or<...> usage to combine with With<...> but it seems to be only for the component inside the same entity ?

Here two functions doing the same thing after filtering the good component With to illustrate :

fn keyboard_input_camera(
    mut query: Query<&mut Transform, With<CameraMain>>,
    keys: Res<ButtonInput<KeyCode>>,
) {
    for mut transform in query.iter_mut() {
        if keys.pressed(KeyCode::ArrowLeft) {
            transform.translation.x -= MOVE_CROSS_SPEED;
        }
    }
}

fn keyboard_input_player(
    mut query: Query<&mut Transform, With<Player>>,
    keys: Res<ButtonInput<KeyCode>>,
) {
    for mut transform in query.iter_mut() {
        if keys.pressed(KeyCode::ArrowLeft) {
            transform.translation.x -= MOVE_CROSS_SPEED;
        }
    }
}

How about using generics like this?

use bevy::prelude::*;

fn main() {
    App::new()
        .add_systems(
            Update,
            (keyboard_input::<CameraMain>, keyboard_input::<Player>),
        )
        .run();
}

fn keyboard_input<T: Component>(
    mut query: Query<&mut Transform, With<T>>,
    keys: Res<ButtonInput<KeyCode>>,
) {
    for mut transform in query.iter_mut() {
        if keys.pressed(KeyCode::ArrowLeft) {
            transform.translation.x -= MOVE_CROSS_SPEED;
        }
    }
}

const MOVE_CROSS_SPEED: f32 = 1.0;

#[derive(Component)]
struct CameraMain;

#[derive(Component)]
struct Player;
3 Likes

I was too focused on the With filter. Thank you so much.