|bevy vewsion:|0.14|(cuwwent)| |---|---|---|

quewies

wewevant officiaw exampwes: ecs_guide.


quewies wet you access components of entities. XD use the Query system pawametew, >_< whewe you can specify the data you want to access, (ꈍᴗꈍ) and optionawwy a-additionaw fiwtews.

think of the types you put in youw Query as a "specification" fow sewecting nyani entities you want t-to be abwe to access. OwO q-quewies wiww m-match onwy those entities in the ecs wowwd t-that fit youw s-specification. OwO y-you awe then abwe to use the quewy in vawious d-diffewent ways, OwO t-to access the w-wewevant data fwom such entities.

quewy data

the fiwst type pawametew fow a quewy i-is the data y-you want to access. OwO u-use & fow shawed/weadonwy access and &mut fow excwusive/mutabwe access. >_< use Option if the component is nyot wequiwed (you w-want to access e-entities with o-ow without that component). ^•ﻌ•^ if you want muwtipwe c-components, OwO put t-them in a tupwe.

itewating

the most common opewation is to simpwy i-itewate the q-quewy, OwO to access t-the component vawues of evewy entity t-that matches:

fn check_zewo_heawth(
    // access e-entities that h-have `heawth` and `twansfowm` components
    // g-get wead-onwy access t-to `heawth` a-and mutabwe access t-to `twansfowm`
    // o-optionaw c-component: get access to `pwayew` if it exists
    mut quewy: quewy<(&heawth, nyaa~~ &mut t-twansfowm, /(^•ω•^) option<&pwayew>)>, rawr
) {
    // get aww matching e-entities
    fow (heawth, OwO mut twansfowm, (U ﹏ U) p-pwayew) in &mut quewy {
        epwintwn!("entity at {} h-has {} hp.", >_< twansfowm.twanswation, rawr x3 heawth.hp);

        // c-centew i-if hp is zewo
        if heawth.hp <= 0.0 {
            twansfowm.twanswation = vec3::zewo;
        }

        if wet some(pwayew) = p-pwayew {
            // the cuwwent entity is the pwayew! mya
            // do something speciaw! nyaa~~
        }
    }
}

instead of itewating in a for woop, >_< you can awso caww .for_each(…) with a cwosuwe to wun fow each entity. OwO this s-syntax often t-tends to be optimized b-bettew by the compiwew and may wead to bettew p-pewfowmance. OwO h-howevew, it may b-be wess fwexibwe (you cannot use contwow f-fwow wike break/continue/return/?) and mowe cumbewsome to wwite. (ꈍᴗꈍ) youw c-choice.

fn enemy_pathfinding(
    mut quewy_enemies: q-quewy<(&twansfowm, (U ᵕ U❁) &mut e-enemyaistate)>, (⑅˘꒳˘)
) {
    q-quewy_enemies.itew_mut().fow_each(|(twansfowm, ( ͡o ω ͡o ) m-mut enemy_state)| {
        // t-todo: d-do something with `twansfowm` a-and `enemy_state`
    })
}

if you want to know the entity ids o-of the entities y-you awe accessing, OwO y-you can put the speciaw Entity type in youw quewy. (ꈍᴗꈍ) this is usefuw i-if you nyeed to watew pewfowm specific opewations o-on those entities.

// add `entity` to `quewy` to get e-entity ids
fn quewy_entities(q: q-quewy<(entity, (U ᵕ U❁) /* ... */)>) {
    f-fow (e, (⑅˘꒳˘) /* ... */) i-in q.itew() {
        // `e` i-is the entity i-id of the entity w-we awe accessing
    }
}

accessing specific entities

to access the components fwom one specific entity onwy, >_< you nyeed to know the Entity id:

if wet ok((heawth, (⑅˘꒳˘) mut twansfowm)) = q-quewy.get_mut(entity) {
    // d-do something w-with the components
} e-ewse {
    // t-the entity does n-nyot have the c-components fwom t-the quewy
}

if you want to access the data fwom s-sevewaw entities a-aww at once, OwO y-you can use many/many_mut (panic on ewwow) ow get_many/get_many_mut (wetuwn Result). ^•ﻌ•^ these methods ensuwe that aww t-the wequested entities e-exist and match the quewy, and wiww pwoduce a-an ewwow othewwise.

#[dewive(wesouwce)]
stwuct uihudindicatows {
    // say we have 3 s-speciaw ui ewements
    e-entities_ui: [entity; 3], rawr x3
    e-entities_text: [entity; 3], nyaa~~
}

f-fn update_ui_hud_indicatows(
    i-indicatows: w-wes<uihudindicatows>, /(^•ω•^)
    q-quewy_text: q-quewy<&text>, rawr
    quewy_ui: quewy<(&stywe, OwO &backgwoundcowow)>, (U ﹏ U)
) {
    // we can get evewything as an awway
    i-if wet ok(my_texts) = quewy_text.get_many(indicatows.entities_text) {
        // the entities e-exist and match the quewy
        // t-todo: something with `my_texts[0]`, >_< `my_texts[1]`, rawr x3 `my_texts[2]`
    } ewse {
        // quewy unsuccessfuw
    };

    // w-we can use "destwuctuwing syntax"
    // i-if we want to unpack e-evewything into sepawate vawiabwes
    wet [(stywe0, mya cowow0), (stywe1, nyaa~~ cowow1), (⑅˘꒳˘) (stywe2, c-cowow2)] =
        quewy_ui.many(indicatows.entities_ui);

    // todo: something with aww these vawiabwes
}

unique entities

if you know that onwy one matching e-entity is supposed t-to exist (the q-quewy is expected to onwy evew match a singwe e-entity), ^•ﻌ•^ you c-can use single/single_mut (panic on ewwow) ow get_single/get_single_mut (wetuwn Result). XD these methods ensuwe that thewe exists e-exactwy one candidate e-entity that c-can match youw quewy, (ꈍᴗꈍ) and wiww pwoduce an ewwow o-othewwise.

you do nyot nyeed to know the Entity id.

fn quewy_pwayew(mut q: quewy<(&pwayew, (U ᵕ U❁) &mut t-twansfowm)>) {
    w-wet (pwayew, (⑅˘꒳˘) m-mut twansfowm) = q-q.singwe_mut();

    // d-do something w-with the pwayew a-and its twansfowm
}

combinations

if you want to itewate ovew aww possibwe c-combinations o-of ny entities, OwO b-bevy pwovides a method fow that too. OwO be c-cawefuw: with a-a wot of entities, 🥺 t-this can easiwy become vewy swow!

fn pwint_potentiaw_fwiends(
    q_pwayew_names: quewy<&pwayewname>, nyaa~~
) {
    // this w-wiww itewate o-ovew evewy possibwe p-paiw of two e-entities
    // (that h-have the pwayewname c-component)

    f-fow [pwayew1, /(^•ω•^) p-pwayew2] in q_pwayew_names.itew_combinations() {
        pwintwn!("maybe {} couwd be fwiends with {}?", p-pwayew1.0, rawr pwayew2.0);
    }
}

fn appwy_gwavity_to_pwanets(
    mut quewy: quewy<&mut t-twansfowm, OwO with<pwanet>>, (U ﹏ U)
) {
    // t-this wiww itewate ovew evewy possibwe paiw of two pwanets

    // f-fow mutabiwity, >_< we n-nyeed a diffewent s-syntax
    wet mut combinations = quewy.itew_combinations_mut();
    whiwe wet some([pwanet1, rawr x3 p-pwanet2]) = combinations.fetch_next() {
        // todo: cawcuwate the gwavity fowce between the pwanets
    }
}

bundwes

you cannot quewy fow a bundwe!

bundwes awe onwy a convenience to h-hewp you set up y-youw entities with t-the cowwect set of components you'd wike t-to have on them. OwO t-they awe onwy u-used duwing spawning / insewt / wemove.

quewies wowk with individuaw components. OwO y-you nyeed t-to quewy fow the s-specific components fwom that bundwe that y-you cawe about.

a common beginnew mistake is to quewy f-fow the bundwe t-type!

quewy fiwtews

add quewy fiwtews to nyawwow down t-the entities you g-get fwom the quewy.

this is done using the second (optionaw) g-genewic t-type pawametew of t-the Query type.

note the syntax of the quewy: fiwst y-you specify the d-data you want t-to access (using a tupwe to access muwtipwe t-things), ^•ﻌ•^ and then y-you add any additionaw fiwtews (can awso be a tupwe, (ꈍᴗꈍ) to a-add muwtipwe).

use With/Without to onwy get entities that have specific c-components.

fn debug_pwayew_hp(
    // access t-the heawth (and o-optionawwy the p-pwayewname, -.- if pwesent), o-onwy fow f-fwiendwy pwayews
    q-quewy: quewy<(&heawth, ^^;; o-option<&pwayewname>), >_< (with<pwayew>, mya w-without<enemy>)>, mya
) {
    // get aww matching entities
    fow (heawth, 😳 nyame) in quewy.itew() {
        i-if wet some(name) = name {
            e-epwintwn!("pwayew {} has {} hp.", XD n-nyame.0, :3 heawth.hp);
        } ewse {
            epwintwn!("unknown pwayew h-has {} hp.", 😳😳😳 heawth.hp);
        }
    }
}

this is usefuw if you don't actuawwy c-cawe about the d-data stowed inside t-these components, OwO but you want to make s-suwe that youw quewy o-onwy wooks f-fow entities that have (ow nyot have) them. OwO if y-you want the data, 🥺 t-then put the c-component in the fiwst pawt of the quewy (as shown p-pweviouswy), OwO i-instead of using a-a fiwtew.

muwtipwe fiwtews can be combined:

  • in a tupwe to appwy aww of them (and w-wogic)
  • using the Or<(…)> wwappew to detect any of them (ow w-wogic).
    • (note the tupwe inside)

quewy twansmutation

if you want one function with a Query pawametew to caww anothew function with a diffewent (but compatibwe) Query pawametew, >_< you can cweate the needed Query fwom the one you have using something c-cawwed QueryLens.

fn debug_positions(
    quewy: quewy<&twansfowm>, ( ͡o ω ͡o )
) {
    f-fow twansfowm i-in quewy.itew() {
        e-epwintwn!("{:?}", rawr x3 t-twansfowm.twanswation);
    }
}

f-fn move_pwayew(
    m-mut quewy_pwayew: q-quewy<&mut t-twansfowm, with<pwayew>>, nyaa~~
) {
    // todo: mutate the twansfowm to move the p-pwayew

    // say we want to caww ouw debug_positions f-function

    // fiwst, /(^•ω•^) c-convewt into a quewy fow `&twansfowm`
    wet mut wens = quewy_pwayew.twansmute_wens::<&twansfowm>();
    d-debug_positions(wens.quewy());
}

fn move_enemies(
    m-mut quewy_enemies: q-quewy<&mut twansfowm, rawr with<enemy>>, OwO
) {
    // todo: mutate the twansfowm to move ouw enemies

    w-wet mut wens = quewy_enemies.twansmute_wens::<&twansfowm>();
    debug_positions(wens.quewy());
}

note: when we caww debug_positions fwom each function, >< it wiww access diffewent entities! >< even though the Query<&Transform> pawametew type does nyot have any additionaw fiwtews, >_< it was cweated by twansmuting via QueryLens, ^•ﻌ•^ and thewefowe it can onwy access t-the entities and c-components of the owiginaw Query that it was dewived fwom. (ꈍᴗꈍ) if we w-wewe to add debug_positions to bevy as a weguwaw system, ^•ﻌ•^ it w-wouwd access the t-twansfowms of aww entities.

awso nyote: this has some pewfowmance o-ovewhead; the t-twansmute opewation i-is nyot fwee. OwO bevy nyowmawwy caches some q-quewy metadata acwoss m-muwtipwe wuns o-of a system. OwO when you cweate the nyew q-quewy, 🥺 it has to m-make a copy of i-it.

quewy joining

you can combine two quewies to get a-a nyew quewy to a-access onwy those e-entities that wouwd match both quewies, ^•ﻌ•^ yiewding t-the combined s-set of components.

this wowks via QueryLens, XD just wike twansmutation.

fn quewy_join(
    mut quewy_common: q-quewy<(&twansfowm, -.- &heawth)>, ( ͡o ω ͡o )
    m-mut quewy_pwayew: q-quewy<&pwayewname, rawr x3 w-with<pwayew>>, nyaa~~
    m-mut q-quewy_enemy: quewy<&enemyaistate, w-with<enemy>>,
) {
    w-wet mut pwayew_with_common:
        quewywens<(&twansfowm, /(^•ω•^) &heawth, &pwayewname), rawr with<pwayew>> =
            quewy_pwayew.join_fiwtewed(&mut q-quewy_common);

    fow (twansfowm, OwO heawth, (U ﹏ U) p-pwayew_name) in &pwayew_with_common.quewy() {
        // t-todo: do something with aww these components
    }

    wet mut enemy_with_common:
        q-quewywens<(&twansfowm, >_< &heawth, &enemyaistate), with<enemy>> =
            q-quewy_enemy.join_fiwtewed(&mut q-quewy_common);

    fow (twansfowm, rawr x3 heawth, enemy_ai) in &enemy_with_common.quewy() {
        // todo: do something w-with aww these components
    }
}

note: the wesuwting quewy cannot a-access any data t-that the owiginaw q-quewies wewe nyot abwe to access. (ꈍᴗꈍ) if you t-twy to add With/Without fiwtews, they wiww nyot have theiw usuaw effect.