Tainted \\ Coders

Custom Queries

Last updated:

Instead of using long winded tuple queries like:

fn print_player_status(query: Query<(Health, Ammo, Player)>) {
    // ..
}

We can create our own custom queries:

#![allow(dead_code)]
use bevy::{
    ecs::query::QueryData,
    prelude::*,
};
use std::fmt::Debug;

#[derive(Component, Debug)]
struct Health(f32);

#[derive(Component, Debug)]
struct Player;

#[derive(Component, Debug)]
struct Ammo(f32);

#[derive(QueryData)]
#[query_data(derive(Debug))]
struct PlayerQuery {
    entity: Entity,
    health: &'static Health,
    ammo: &'static Ammo,
    player: &'static Player,
}

fn print_player_status(query: Query<PlayerQuery>) {
    for player in query.iter() {
        println!(
            "Player {:?} has {:?} health and {:?} ammo",
            player.entity,
            player.health,
            player.ammo
        );
    }
}

When we derive from QueryData we get a number of benefits:

  • Reusability across multiple systems.
  • There is no need to destructure a tuple since all fields are named.
  • Subqueries can be composed together to create a more complex query.
  • Methods can be implemented for the query items.
  • There is no hardcoded limit (usually 15 with tuples) on the number of elements.

Read more