Skip to main content

Query

Struct Query 

Source
pub struct Query<'world, 'state, D, F = ()>
where D: QueryData, F: QueryFilter,
{ /* private fields */ }
Expand description

A system parameter that provides selective access to the Component data stored in a World.

Queries enable systems to access entity identifiers and components without requiring direct access to the World. Its iterators and getter methods return query items, which are types containing data related to an entity.

Query is a generic data structure that accepts two type parameters:

  • D (query data): The type of data fetched by the query, which will be returned as the query item. Only entities that match the requested data will generate an item. Must implement the QueryData trait.
  • F (query filter): An optional set of conditions that determine whether query items should be kept or discarded. This defaults to unit, which means no additional filters will be applied. Must implement the QueryFilter trait.

§Similar parameters

Query has few sibling SystemParams, which perform additional validation:

These parameters will prevent systems from running if their requirements are not met.

§System parameter declaration

A query should always be declared as a system parameter. This section shows the most common idioms involving the declaration of Query.

§Component access

You can fetch an entity’s component by specifying a reference to that component in the query’s data parameter:

// A component can be accessed by a shared reference...
fn immutable_query(query: Query<&ComponentA>) {
    // ...
}

// ...or by a mutable reference.
fn mutable_query(query: Query<&mut ComponentA>) {
    // ...
}

Note that components need to be behind a reference (& or &mut), or the query will not compile:

ⓘ
// This needs to be `&ComponentA` or `&mut ComponentA` in order to compile.
fn invalid_query(query: Query<ComponentA>) {
    // ...
}

§Query filtering

Setting the query filter type parameter will ensure that each query item satisfies the given condition:

// `ComponentA` data will be accessed, but only for entities that also contain `ComponentB`.
fn filtered_query(query: Query<&ComponentA, With<ComponentB>>) {
    // ...
}

Note that the filter is With<ComponentB>, not With<&ComponentB>. Unlike query data, With does not require components to be behind a reference.

§QueryData or QueryFilter tuples

Using tuples, each Query type parameter can contain multiple elements.

In the following example two components are accessed simultaneously, and the query items are filtered on two conditions:

fn complex_query(
    query: Query<(&mut ComponentA, &ComponentB), (With<ComponentC>, Without<ComponentD>)>
) {
    // ...
}

Note that this currently only works on tuples with 15 or fewer items. You may nest tuples to get around this limit:

fn nested_query(
    query: Query<(&ComponentA, &ComponentB, (&mut ComponentC, &mut ComponentD))>
) {
    // ...
}

§Entity identifier access

You can access Entity, the entity identifier, by including it in the query data parameter:

fn entity_id_query(query: Query<(Entity, &ComponentA)>) {
    // ...
}

Be aware that Entity is not a component, so it does not need to be behind a reference.

§Optional component access

A component can be made optional by wrapping it into an Option. In the following example, a query item will still be generated even if the queried entity does not contain ComponentB. When this is the case, Option<&ComponentB>’s corresponding value will be None.

// Queried items must contain `ComponentA`. If they also contain `ComponentB`, its value will
// be fetched as well.
fn optional_component_query(query: Query<(&ComponentA, Option<&ComponentB>)>) {
    // ...
}

Optional components can hurt performance in some cases, so please read the performance section to learn more about them. Additionally, if you need to declare several optional components, you may be interested in using AnyOf.

§Disjoint queries

A system cannot contain two queries that break Rust’s mutability rules, or else it will panic when initialized. This can often be fixed with the Without filter, which makes the queries disjoint.

In the following example, the two queries can mutably access the same &mut Health component if an entity has both the Player and Enemy components. Bevy will catch this and panic, however, instead of breaking Rust’s mutability rules:

ⓘ
fn randomize_health(
    player_query: Query<&mut Health, With<Player>>,
    enemy_query: Query<&mut Health, With<Enemy>>,
) {
    // ...
}

Adding a Without filter will disjoint the queries. In the following example, any entity that has both the Player and Enemy components will be excluded from both queries:

fn randomize_health(
    player_query: Query<&mut Health, (With<Player>, Without<Enemy>)>,
    enemy_query: Query<&mut Health, (With<Enemy>, Without<Player>)>,
) {
    // ...
}

An alternative solution to this problem would be to wrap the conflicting queries in ParamSet.

§Whole Entity Access

EntityRef can be used in a query to gain read-only access to all components of an entity. This is useful when dynamically fetching components instead of baking them into the query type.

fn all_components_query(query: Query<(EntityRef, &ComponentA)>) {
    // ...
}

As EntityRef can read any component on an entity, a query using it will conflict with any mutable component access.

ⓘ
// `EntityRef` provides read access to *all* components on an entity. When combined with
// `&mut ComponentA` in the same query, it creates a conflict because `EntityRef` could read
// `&ComponentA` while `&mut ComponentA` attempts to modify it - violating Rust's borrowing
// rules.
fn invalid_query(query: Query<(EntityRef, &mut ComponentA)>) {
    // ...
}

It is strongly advised to couple EntityRef queries with the use of either With / Without filters or ParamSets. Not only does this improve the performance and parallelization of the system, but it enables systems to gain mutable access to other components:

// The first query only reads entities that have `ComponentA`, while the second query only
// modifies entities that *don't* have `ComponentA`. Because neither query will access the same
// entity, this system does not conflict.
fn disjoint_query(
    query_a: Query<EntityRef, With<ComponentA>>,
    query_b: Query<&mut ComponentB, Without<ComponentA>>,
) {
    // ...
}

The fundamental rule: EntityRef’s ability to read all components means it can never coexist with mutable access. With / Without filters can guarantee this by keeping the queries on completely separate entities.

§Accessing query items

The following table summarizes the behavior of safe methods that can be used to get query items:

Query methodsEffect
iter[_mut]Returns an iterator over all query items.
iter[_mut]().for_each(),
par_iter[_mut]
Runs a specified function for each query item.
iter_many[_unique][_mut]Iterates over query items that match a list of entities.
iter_combinations[_mut]Iterates over all combinations of query items.
single[_mut]Returns a single query item if only one exists.
get[_mut]Returns the query item for a specified entity.
get_many[_unique][_mut]Returns all query items that match a list of entities.

There are two methods for each type of query operation: immutable and mutable (ending with _mut). When using immutable methods, the query items returned are of type ROQueryItem, a read-only version of the query item. In this circumstance, every mutable reference in the query fetch type parameter is substituted by a shared reference.

§Performance

Creating a Query is a low-cost constant operation. Iterating it, on the other hand, fetches data from the world and generates items, which can have a significant computational cost.

Two systems cannot be executed in parallel if both access the same component type where at least one of the accesses is mutable. Because of this, it is recommended for queries to only fetch mutable access to components when necessary, since immutable access can be parallelized.

Query filters (With / Without) can improve performance because they narrow the kinds of entities that can be fetched. Systems that access fewer kinds of entities are more likely to be parallelized by the scheduler.

On the other hand, be careful using optional components (Option<&ComponentA>) and EntityRef because they broaden the amount of entities kinds that can be accessed. This is especially true of a query that only fetches optional components or EntityRef, as the query would iterate over all entities in the world.

There are two types of component storage types: Table and SparseSet. Table offers fast iteration speeds, but slower insertion and removal speeds. SparseSet is the opposite: it offers fast component insertion and removal speeds, but slower iteration speeds.

The following table compares the computational complexity of the various methods and operations, where:

  • n is the number of entities that match the query.
  • r is the number of elements in a combination.
  • k is the number of involved entities in the operation.
  • a is the number of archetypes in the world.
  • C is the binomial coefficient, used to count combinations. nCr is read as “n choose r” and is equivalent to the number of distinct unordered subsets of r elements that can be taken from a set of n elements.
Query operationComputational complexity
iter[_mut]O(n)
iter[_mut]().for_each(),
par_iter[_mut]
O(n)
iter_many[_mut]O(k)
iter_combinations[_mut]O(nCr)
single[_mut]O(a)
get[_mut]O(1)
get_manyO(k)
get_many_mutO(k2)
Archetype-based filtering (With, Without, Or)O(a)
Change detection filtering (Added, Changed, Spawned)O(a + n)

§Iterator::for_each

The for_each methods appear to be generally faster than for-loops when run on worlds with high archetype fragmentation, and may enable additional optimizations like autovectorization. It is strongly advised to only use Iterator::for_each if it tangibly improves performance. Always profile or benchmark before and after the change!

fn system(query: Query<&ComponentA>) {
    // This may result in better performance...
    query.iter().for_each(|component| {
        // ...
    });

    // ...than this. Always benchmark to validate the difference!
    for component in query.iter() {
        // ...
    }
}

Implementations§

Source§

impl<'w, 's, D, F> Query<'w, 's, D, F>
where D: QueryData, F: QueryFilter,

Source

pub fn related<R>(&'w self, entity: Entity) -> Option<Entity>
where R: Relationship, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w R>,

If the given entity contains the R Relationship component, returns the target entity of that relationship.

Source

pub fn relationship_sources<S>( &'w self, entity: Entity, ) -> impl Iterator<Item = Entity> + 'w
where S: RelationshipTarget, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w S>,

If the given entity contains the S RelationshipTarget component, returns the source entities stored on that component.

Source

pub fn root_ancestor<R>(&'w self, entity: Entity) -> Entity
where R: Relationship, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w R>,

Recursively walks up the tree defined by the given R Relationship until there are no more related entities, returning the “root entity” of the relationship hierarchy.

§Warning

For relationship graphs that contain loops, this could loop infinitely. If your relationship is not a tree (like Bevy’s hierarchy), be sure to stop if you encounter a duplicate entity.

Source

pub fn iter_leaves<S>( &'w self, entity: Entity, ) -> impl Iterator<Item = Entity> + use<'w, 's, S, D, F>

Iterates all “leaf entities” as defined by the RelationshipTarget hierarchy.

§Warning

For relationship graphs that contain loops, this could loop infinitely. If your relationship is not a tree (like Bevy’s hierarchy), be sure to stop if you encounter a duplicate entity.

Examples found in repository?
examples/ui/layout/size_constraints.rs (line 249)
198fn radio_button_scene(
199    constraint: Constraint,
200    action: RadioButtonValue,
201    label: String,
202    active: bool,
203) -> impl Scene {
204    bsn! {
205        RadioButton
206        Node {
207            align_items: AlignItems::Center,
208            justify_content: JustifyContent::Center,
209            border: UiRect::all(px(2)),
210            margin: UiRect::horizontal(px(2)),
211        }
212        BorderColor::all(if active {
213            ACTIVE_BORDER_COLOR
214        } else {
215            INACTIVE_BORDER_COLOR
216        })
217        constraint
218        action
219        Children [
220            Node {
221                width: px(100),
222                justify_content: JustifyContent::Center,
223            }
224            BackgroundColor({if active {
225                ACTIVE_INNER_COLOR
226            } else {
227                INACTIVE_INNER_COLOR
228            }})
229            Children [
230                Text(label)
231                @font_style_scene()
232                TextColor({if active {
233                    ACTIVE_TEXT_COLOR
234                } else {
235                    UNHOVERED_TEXT_COLOR
236                }})
237                TextLayout::justify(Justify::Center)
238            ]
239        ]
240        // Observers for updating text on hover/leave
241        on(|event: On<PointerOver>,
242            has_checked_query: Query<&Checked>,
243            child_q: Query<&Children>,
244            mut commands: Commands| {
245            if has_checked_query.contains(event.entity) {
246                return;
247            }
248
249            for text_entity in child_q.iter_leaves(event.entity) {
250                commands.entity(text_entity).insert(TextColor(HOVERED_TEXT_COLOR));
251            }
252        })
253        on(|event: On<PointerOut>,
254            has_checked_query: Query<&Checked>,
255            child_q: Query<&Children>,
256            mut commands: Commands| {
257            if has_checked_query.contains(event.entity) {
258                return;
259            }
260
261            for text_entity in child_q.iter_leaves(event.entity) {
262                commands.entity(text_entity).insert(TextColor(UNHOVERED_TEXT_COLOR));
263            }
264        })
265    }
266}
267
268/// This system updates the Bar when a new value for a constraint is selected, and marks
269/// the radio button as the one currently selected
270fn on_value_change_constraints(
271    event: On<ValueChange<Entity>>,
272    new_setting_query: Query<
273        (&Constraint, &RadioButtonValue, Entity, &Children),
274        (With<RadioButton>, Without<Checked>),
275    >,
276    previous_query: Query<
277        (&Constraint, &RadioButtonValue, Entity, &Children),
278        (With<RadioButton>, With<Checked>),
279    >,
280    child_q: Query<&Children>,
281    mut commands: Commands,
282    mut bar_node: Single<&mut Node, With<Bar>>,
283) {
284    if let Ok((constraint, value, entity, children)) = new_setting_query.get(event.value) {
285        for (previous_constraint, previous_value, previous_entity, previous_children) in
286            previous_query.iter()
287        {
288            if constraint == previous_constraint && value == previous_value {
289                // There is no change in constraint. We can exit out early.
290                return;
291            } else if constraint == previous_constraint {
292                commands.entity(previous_entity).remove::<Checked>();
293                commands
294                    .entity(previous_entity)
295                    .insert(BorderColor::all(INACTIVE_BORDER_COLOR));
296                // radio button entities only have one child which contains the inner background color.
297                commands
298                    .entity(*previous_children.first().unwrap())
299                    .insert(BackgroundColor(INACTIVE_INNER_COLOR));
300                for text_entity in child_q.iter_leaves(previous_entity) {
301                    commands
302                        .entity(text_entity)
303                        .insert(TextColor(UNHOVERED_TEXT_COLOR));
304                }
305
306                commands.entity(entity).insert(Checked);
307                commands
308                    .entity(entity)
309                    .insert(BorderColor::all(ACTIVE_BORDER_COLOR));
310                commands
311                    .entity(*children.first().unwrap())
312                    .insert(BackgroundColor(ACTIVE_INNER_COLOR));
313                for text_entity in child_q.iter_leaves(entity) {
314                    commands
315                        .entity(text_entity)
316                        .insert(TextColor(ACTIVE_TEXT_COLOR));
317                }
318            }
319        }
320
321        match constraint {
322            Constraint::FlexBasis => {
323                bar_node.flex_basis = value.0;
324            }
325            Constraint::Width => {
326                bar_node.width = value.0;
327            }
328            Constraint::MinWidth => {
329                bar_node.min_width = value.0;
330            }
331            Constraint::MaxWidth => {
332                bar_node.max_width = value.0;
333            }
334        }
335    }
336}
Source

pub fn iter_siblings<R>( &'w self, entity: Entity, ) -> impl Iterator<Item = Entity> + 'w
where R: Relationship, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = (Option<&'w R>, Option<&'w <R as Relationship>::RelationshipTarget>)>,

Iterates all sibling entities that also have the R Relationship with the same target entity.

Source

pub fn iter_descendants<S>( &'w self, entity: Entity, ) -> DescendantIter<'w, 's, D, F, S> ⓘ
where S: RelationshipTarget, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w S>,

Iterates all descendant entities as defined by the given entity’s RelationshipTarget and their recursive RelationshipTarget.

§Warning

For relationship graphs that contain loops, this could loop infinitely. If your relationship is not a tree (like Bevy’s hierarchy), be sure to stop if you encounter a duplicate entity.

Examples found in repository?
examples/gltf/update_gltf_scene.rs (line 65)
57fn move_scene_entities(
58    time: Res<Time>,
59    moved_scene: Query<Entity, With<MovedScene>>,
60    children: Query<&Children>,
61    mut transforms: Query<&mut Transform>,
62) {
63    for moved_scene_entity in &moved_scene {
64        let mut offset = 0.;
65        for entity in children.iter_descendants(moved_scene_entity) {
66            if let Ok(mut transform) = transforms.get_mut(entity) {
67                transform.translation = Vec3::new(
68                    offset * ops::sin(time.elapsed_secs()) / 20.,
69                    0.,
70                    ops::cos(time.elapsed_secs()) / 20.,
71                );
72                offset += 0.5;
73            }
74        }
75    }
76}
More examples
Hide additional examples
examples/animation/morph_targets.rs (line 66)
58fn play_animation_when_ready(
59    scene_ready: On<WorldInstanceReady>,
60    mut commands: Commands,
61    children: Query<&Children>,
62    animations_to_play: Query<&AnimationToPlay>,
63    mut players: Query<&mut AnimationPlayer>,
64) {
65    if let Ok(animation_to_play) = animations_to_play.get(scene_ready.entity) {
66        for child in children.iter_descendants(scene_ready.entity) {
67            if let Ok(mut player) = players.get_mut(child) {
68                player.play(animation_to_play.index).repeat();
69
70                commands
71                    .entity(child)
72                    .insert(AnimationGraphHandle(animation_to_play.graph_handle.clone()));
73            }
74        }
75    }
76}
tests/3d/test_skinned_mesh_bounds.rs (line 105)
97fn play_animation(
98    trigger: On<WorldInstanceReady>,
99    mut commands: Commands,
100    children: Query<&Children>,
101    animations: Query<&PendingAnimation>,
102    mut players: Query<&mut AnimationPlayer>,
103) {
104    if let Ok(PendingAnimation((graph_handle, graph_node_index))) = animations.get(trigger.entity) {
105        for child in children.iter_descendants(trigger.entity) {
106            if let Ok(mut player) = players.get_mut(child) {
107                player.play(*graph_node_index).set_speed(0.6).repeat();
108
109                commands
110                    .entity(child)
111                    .insert(AnimationGraphHandle(graph_handle.clone()));
112            }
113        }
114    }
115
116    commands.entity(trigger.entity).remove::<PendingAnimation>();
117}
examples/stress_tests/many_foxes.rs (line 275)
267fn setup_scene_once_loaded(
268    scene_ready: On<WorldInstanceReady>,
269    animations: Res<Animations>,
270    foxes: Res<Foxes>,
271    mut commands: Commands,
272    children: Query<&Children>,
273    mut players: Query<&mut AnimationPlayer>,
274) {
275    for child in children.iter_descendants(scene_ready.entity) {
276        if let Ok(mut player) = players.get_mut(child) {
277            let playing_animation = player.play(animations.node_indices[0]).repeat();
278            if !foxes.sync {
279                playing_animation.seek_to(scene_ready.entity.index_u32() as f32 / 10.0);
280            }
281            commands.entity(child).insert((
282                AnimationGraphHandle(animations.graph.clone()),
283                AnimationTransitions::default(),
284            ));
285        }
286    }
287}
examples/testbed/3d.rs (line 360)
353    fn pause_animation_frame(
354        scene_ready: On<WorldInstanceReady>,
355        children: Query<&Children>,
356        mut commands: Commands,
357        animation: Res<Animation>,
358        mut players: Query<(Entity, &mut AnimationPlayer)>,
359    ) {
360        for child in children.iter_descendants(scene_ready.entity) {
361            if let Ok((entity, mut player)) = players.get_mut(child) {
362                let mut transitions = AnimationTransitions::new();
363                transitions
364                    .play(&mut player, animation.animation, Duration::ZERO)
365                    .seek_to(0.5)
366                    .pause();
367
368                commands
369                    .entity(entity)
370                    .insert(AnimationGraphHandle(animation.graph.clone()))
371                    .insert(transitions);
372            }
373        }
374    }
375}
376
377mod gizmos {
378    use bevy::{color::palettes::css::*, prelude::*};
379
380    pub fn setup(mut commands: Commands) {
381        commands.spawn((
382            Camera3d::default(),
383            Transform::from_xyz(-1.0, 2.5, 6.5).looking_at(Vec3::ZERO, Vec3::Y),
384            DespawnOnExit(super::Scene::Gizmos),
385        ));
386    }
387
388    pub fn draw_gizmos(mut gizmos: Gizmos) {
389        gizmos.cube(
390            Transform::from_translation(Vec3::X * -1.75).with_scale(Vec3::splat(1.25)),
391            RED,
392        );
393        gizmos
394            .sphere(Isometry3d::from_translation(Vec3::X * -3.5), 0.75, GREEN)
395            .resolution(30_000 / 3);
396
397        gizmos.text(
398            Isometry3d::from_translation(Vec3::Y * 1.5),
399            "text gizmo",
400            0.3,
401            Vec2 { x: 0., y: 0. },
402            Color::WHITE,
403        );
404
405        // 3d grids with all variations of outer edges on or off
406        for i in 0..8 {
407            let x = 1.5 * (i % 4) as f32;
408            let y = 1.0 * (0.5 - (i / 4) as f32);
409            let mut grid = gizmos.grid_3d(
410                Isometry3d::from_translation(Vec3::new(x, y, 0.0)),
411                UVec3::new(5, 4, 3),
412                Vec3::splat(0.175),
413                Color::WHITE,
414            );
415            if i & 1 > 0 {
416                grid = grid.outer_edges_x();
417            }
418            if i & 2 > 0 {
419                grid = grid.outer_edges_y();
420            }
421            if i & 4 > 0 {
422                grid.outer_edges_z();
423            }
424        }
425    }
426}
427
428mod gltf_coordinate_conversion {
429    use bevy::{
430        color::palettes::basic::*,
431        gltf::{convert_coordinates::GltfConvertCoordinates, GltfLoaderSettings},
432        prelude::*,
433        world_serialization::WorldInstanceReady,
434    };
435
436    const CURRENT_SCENE: super::Scene = super::Scene::GltfCoordinateConversion;
437
438    pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
439        commands.spawn((
440            Camera3d::default(),
441            Transform::from_xyz(-4.0, 4.0, -5.0).looking_at(Vec3::ZERO, Vec3::Y),
442            DespawnOnExit(CURRENT_SCENE),
443        ));
444
445        commands.spawn((
446            DirectionalLight {
447                color: BLUE.into(),
448                ..default()
449            },
450            Transform::IDENTITY.looking_to(Dir3::Z, Dir3::Y),
451            DespawnOnExit(CURRENT_SCENE),
452        ));
453
454        commands.spawn((
455            DirectionalLight {
456                color: RED.into(),
457                ..default()
458            },
459            Transform::IDENTITY.looking_to(Dir3::X, Dir3::Y),
460            DespawnOnExit(CURRENT_SCENE),
461        ));
462
463        commands.spawn((
464            DirectionalLight {
465                color: GREEN.into(),
466                ..default()
467            },
468            Transform::IDENTITY.looking_to(Dir3::NEG_Y, Dir3::X),
469            DespawnOnExit(CURRENT_SCENE),
470        ));
471
472        commands
473            .spawn((
474                WorldAssetRoot(
475                    asset_server
476                        .load_builder()
477                        .with_settings(|s: &mut GltfLoaderSettings| {
478                            s.convert_coordinates = Some(GltfConvertCoordinates {
479                                rotate_scene_entity: true,
480                                rotate_meshes: true,
481                            });
482                        })
483                        .load(GltfAssetLabel::Scene(0).from_asset("models/Faces/faces.glb")),
484                ),
485                DespawnOnExit(CURRENT_SCENE),
486            ))
487            .observe(show_aabbs);
488    }
489
490    pub fn show_aabbs(
491        scene_ready: On<WorldInstanceReady>,
492        mut commands: Commands,
493        children: Query<&Children>,
494        meshes: Query<(), With<Mesh3d>>,
495    ) {
496        for child in children
497            .iter_descendants(scene_ready.entity)
498            .filter(|&e| meshes.contains(e))
499        {
500            commands.entity(child).insert(ShowAabbGizmo {
501                color: Some(BLACK.into()),
502            });
503        }
504    }
examples/stress_tests/many_morph_targets.rs (line 395)
384fn play_animation(
385    trigger: On<WorldInstanceReady>,
386    mut commands: Commands,
387    args: Res<Args>,
388    children: Query<&Children>,
389    animations_to_play: Query<&AnimationToPlay>,
390    mut players: Query<&mut AnimationPlayer>,
391) {
392    if args.weights == ArgWeights::Animated
393        && let Ok(animation_to_play) = animations_to_play.get(trigger.entity)
394    {
395        for child in children.iter_descendants(trigger.entity) {
396            if let Ok(mut player) = players.get_mut(child) {
397                commands
398                    .entity(child)
399                    .insert(AnimationGraphHandle(animation_to_play.graph_handle.clone()));
400
401                player
402                    .play(animation_to_play.index)
403                    .repeat()
404                    .set_speed(animation_to_play.speed);
405            }
406        }
407    }
408}
409
410fn set_weights(
411    trigger: On<WorldInstanceReady>,
412    args: Res<Args>,
413    children: Query<&Children>,
414    mut weight_components: Query<&mut MorphWeights>,
415) {
416    if let Some(weight_value) = match args.weights {
417        ArgWeights::One => Some(1.0),
418        ArgWeights::Zero => Some(0.0),
419        ArgWeights::Tiny => Some(0.00001),
420        _ => None,
421    } {
422        for child in children.iter_descendants(trigger.entity) {
423            if let Ok(mut weight_component) = weight_components.get_mut(child) {
424                weight_component.weights_mut().fill(weight_value);
425            }
426        }
427    }
428}
Source

pub fn iter_descendants_depth_first<S>( &'w self, entity: Entity, ) -> DescendantDepthFirstIter<'w, 's, D, F, S> ⓘ

Iterates all descendant entities as defined by the given entity’s RelationshipTarget and their recursive RelationshipTarget in depth-first order.

§Warning

For relationship graphs that contain loops, this could loop infinitely. If your relationship is not a tree (like Bevy’s hierarchy), be sure to stop if you encounter a duplicate entity.

Source

pub fn iter_ancestors<R>( &'w self, entity: Entity, ) -> AncestorIter<'w, 's, D, F, R> ⓘ
where R: Relationship, <D as QueryData>::ReadOnly: QueryData<Item<'w, 's> = &'w R>,

Iterates all ancestors of the given entity as defined by the R Relationship.

§Warning

For relationship graphs that contain loops, this could loop infinitely. If your relationship is not a tree (like Bevy’s hierarchy), be sure to stop if you encounter a duplicate entity.

Examples found in repository?
examples/ecs/relationships.rs (line 168)
152    fn check_for_cycles(
153        // We want to check every entity for cycles
154        query_to_check: Query<Entity, With<Targeting>>,
155        // Fetch the names for easier debugging.
156        name_query: Query<&Name>,
157        // The targeting_query allows us to traverse the relationship graph.
158        targeting_query: Query<&Targeting>,
159    ) -> Result<(), TargetingCycle> {
160        for initial_entity in query_to_check.iter() {
161            let mut visited = EntityHashSet::new();
162            let mut targeting_name = name_query.get(initial_entity).unwrap().clone();
163            println!("Checking for cycles starting at {targeting_name}",);
164
165            // There's all sorts of methods like this; check the `Query` docs for more!
166            // This would also be easy to do by just manually checking the `Targeting` component,
167            // and calling `query.get(targeted_entity)` on the entity that it targets in a loop.
168            for targeting in targeting_query.iter_ancestors(initial_entity) {
169                let target_name = name_query.get(targeting).unwrap();
170                println!("{targeting_name} is targeting {target_name}",);
171                targeting_name = target_name.clone();
172
173                if !visited.insert(targeting) {
174                    return Err(TargetingCycle {
175                        initial_entity,
176                        visited,
177                    });
178                }
179            }
180        }
181
182        // If we've checked all the entities and haven't found a cycle, we're good!
183        Ok(())
184    }
More examples
Hide additional examples
examples/3d/clustered_decals.rs (line 415)
404fn handle_drag_as_movement(
405    event: On<PointerDrag>,
406    parent_q: Query<&ChildOf>,
407    number_input_q: Query<(), With<FeathersNumberInput>>,
408    mut selections: Query<(&mut Transform, &Selection)>,
409    mouse_motion: Res<AccumulatedMouseMotion>,
410    app_status: Res<AppStatus>,
411) {
412    // If we are currently dragging the number input, do not interpret it as movement
413    // of the selection.
414    if parent_q
415        .iter_ancestors(event.entity)
416        .any(|parent| number_input_q.contains(parent))
417    {
418        return;
419    }
420    for (mut transform, selection) in &mut selections {
421        if app_status.selection != *selection {
422            continue;
423        }
424
425        let position = transform.translation;
426
427        // Convert to spherical coordinates.
428        let radius = position.length();
429        let mut theta = acos(position.y / radius);
430        let mut phi = position.z.signum() * acos(position.x * position.xz().length_recip());
431
432        // Camera movement is the inverse of object movement.
433        let (phi_factor, theta_factor) = match *selection {
434            Selection::Camera => (1.0, -1.0),
435            Selection::DecalA | Selection::DecalB => (-1.0, 1.0),
436        };
437
438        // Adjust the spherical coordinates. Clamp the inclination to (0, π).
439        phi += phi_factor * mouse_motion.delta.x * MOVE_SPEED;
440        theta = f32::clamp(
441            theta + theta_factor * mouse_motion.delta.y * MOVE_SPEED,
442            0.001,
443            PI - 0.001,
444        );
445
446        // Convert spherical coordinates back to Cartesian coordinates.
447        transform.translation =
448            radius * vec3(sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi));
449
450        // Look at the center, but preserve the previous roll angle.
451        let roll = transform.rotation.to_euler(EulerRot::YXZ).2;
452        transform.look_at(Vec3::ZERO, Vec3::Y);
453        let (yaw, pitch, _) = transform.rotation.to_euler(EulerRot::YXZ);
454        transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
455    }
456}
examples/3d/light_textures.rs (line 520)
509fn handle_drag_as_movement(
510    event: On<PointerDrag>,
511    parent_q: Query<&ChildOf>,
512    number_input_q: Query<(), With<FeathersNumberInput>>,
513    mut selections: Query<(&mut Transform, &Selection)>,
514    mouse_motion: Res<AccumulatedMouseMotion>,
515    app_status: Res<AppStatus>,
516) {
517    // If we are currently dragging the number input, do not interpret it as movement
518    // of the selection.
519    if parent_q
520        .iter_ancestors(event.entity)
521        .any(|parent| number_input_q.contains(parent))
522    {
523        return;
524    }
525
526    for (mut transform, selection) in &mut selections {
527        if app_status.selection != *selection {
528            continue;
529        }
530
531        // use simple movement for the point light
532        if *selection == Selection::PointLight {
533            transform.translation +=
534                (mouse_motion.delta * Vec2::new(1.0, -1.0) * MOVE_SPEED).extend(0.0);
535            return;
536        }
537
538        let position = transform.translation;
539
540        // Convert to spherical coordinates.
541        let radius = position.length();
542        let mut theta = acos(position.y / radius);
543        let mut phi = position.z.signum() * acos(position.x * position.xz().length_recip());
544
545        // Camera movement is the inverse of object movement.
546        let (phi_factor, theta_factor) = match *selection {
547            Selection::Camera => (1.0, -1.0),
548            _ => (-1.0, 1.0),
549        };
550
551        // Adjust the spherical coordinates. Clamp the inclination to (0, π).
552        phi += phi_factor * mouse_motion.delta.x * MOVE_SPEED;
553        theta = f32::clamp(
554            theta + theta_factor * mouse_motion.delta.y * MOVE_SPEED,
555            0.001,
556            PI - 0.001,
557        );
558
559        // Convert spherical coordinates back to Cartesian coordinates.
560        transform.translation =
561            radius * vec3(sin(theta) * cos(phi), cos(theta), sin(theta) * sin(phi));
562
563        // Look at the center, but preserve the previous roll angle.
564        let roll = transform.rotation.to_euler(EulerRot::YXZ).2;
565        transform.look_at(Vec3::ZERO, Vec3::Y);
566        let (yaw, pitch, _) = transform.rotation.to_euler(EulerRot::YXZ);
567        transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
568    }
569}
Source§

impl<'w, 's, D, F> Query<'w, 's, D, F>
where D: QueryData, F: QueryFilter,

Source

pub fn as_readonly(&self) -> Query<'_, 's, <D as QueryData>::ReadOnly, F>

Returns another Query from this that fetches the read-only version of the query items.

For example, Query<(&mut D1, &D2, &mut D3), With<F>> will become Query<(&D1, &D2, &D3), With<F>>. This can be useful when working around the borrow checker, or reusing functionality between systems via functions that accept query types.

§See also

into_readonly for a version that consumes the Query to return one with the full 'world lifetime.

Source

pub fn into_readonly(self) -> Query<'w, 's, <D as QueryData>::ReadOnly, F>

Returns another Query from this that fetches the read-only version of the query items.

For example, Query<(&mut D1, &D2, &mut D3), With<F>> will become Query<(&D1, &D2, &D3), With<F>>. This can be useful when working around the borrow checker, or reusing functionality between systems via functions that accept query types.

§See also

as_readonly for a version that borrows the Query instead of consuming it.

Source

pub fn reborrow(&mut self) -> Query<'_, 's, D, F>

Returns a new Query reborrowing the access from this one. The current query will be unusable while the new one exists.

§Example

For example this allows to call other methods or other systems that require an owned Query without completely giving up ownership of it.


fn helper_system(query: Query<&ComponentA>) { /* ... */}

fn system(mut query: Query<&ComponentA>) {
    helper_system(query.reborrow());
    // Can still use query here:
    for component in &query {
        // ...
    }
}
Source

pub unsafe fn reborrow_unsafe(&self) -> Query<'_, 's, D, F>

Returns a new Query reborrowing the access from this one. The current query will still be usable while the new one exists, but must not be used in a way that violates aliasing.

§Safety

This function makes it possible to violate Rust’s aliasing guarantees. You must make sure this call does not result in a mutable or shared reference to a component with a mutable reference.

§See also
Source

pub fn iter(&self) -> QueryIter<'_, 's, <D as QueryData>::ReadOnly, F> ⓘ

Returns an Iterator over the read-only query items.

This iterator is always guaranteed to return results from each matching entity once and only once. Iteration order is not guaranteed.

§Example

Here, the report_names_system iterates over the Player component of every entity that contains it:

fn report_names_system(query: Query<&Player>) {
    for player in &query {
        println!("Say hello to {}!", player.name);
    }
}
§See also

iter_mut for mutable query items.

Examples found in repository?
examples/ecs/system_param.rs (line 31)
30    fn count(&mut self) {
31        self.count.0 = self.players.iter().len();
32    }
More examples
Hide additional examples
tests/window/desktop_request_redraw.rs (line 104)
103fn redraw(mut commands: Commands, query: Query<Entity, With<AnimationActive>>) {
104    if query.iter().next().is_some() {
105        commands.write_message(RequestRedraw);
106    }
107}
examples/usage/context_menu.rs (line 92)
87fn on_trigger_close_menus(
88    _event: On<CloseContextMenus>,
89    mut commands: Commands,
90    menus: Query<Entity, With<ContextMenu>>,
91) {
92    for e in menus.iter() {
93        commands.entity(e).despawn();
94    }
95}
examples/app/headless_renderer.rs (line 318)
316fn image_copy_extract(mut commands: Commands, image_copiers: Extract<Query<&ImageCopier>>) {
317    commands.insert_resource(ImageCopiers(
318        image_copiers.iter().cloned().collect::<Vec<ImageCopier>>(),
319    ));
320}
321
322// Copies image content from render target to buffer
323fn image_copy_driver(
324    render_context: RenderContext,
325    image_copiers: Res<ImageCopiers>,
326    render_queue: Res<RenderQueue>,
327    gpu_images: Res<RenderAssets<bevy::render::texture::GpuImage>>,
328) {
329    for image_copier in image_copiers.iter() {
330        if !image_copier.enabled() {
331            continue;
332        }
333
334        let src_image = gpu_images.get(&image_copier.src_image).unwrap();
335
336        let mut encoder = render_context
337            .render_device()
338            .create_command_encoder(&CommandEncoderDescriptor::default());
339
340        let block_dimensions = src_image.texture_descriptor.format.block_dimensions();
341        let block_size = src_image
342            .texture_descriptor
343            .format
344            .block_copy_size(None)
345            .unwrap();
346
347        // Calculating correct size of image row because
348        // copy_texture_to_buffer can copy image only by rows aligned wgpu::COPY_BYTES_PER_ROW_ALIGNMENT
349        // That's why image in buffer can be little bit wider
350        // This should be taken into account at copy from buffer stage
351        let padded_bytes_per_row = RenderDevice::align_copy_bytes_per_row(
352            (src_image.texture_descriptor.size.width as usize / block_dimensions.0 as usize)
353                * block_size as usize,
354        );
355
356        encoder.copy_texture_to_buffer(
357            src_image.texture.as_image_copy(),
358            TexelCopyBufferInfo {
359                buffer: &image_copier.buffer,
360                layout: TexelCopyBufferLayout {
361                    offset: 0,
362                    bytes_per_row: Some(
363                        std::num::NonZero::<u32>::new(padded_bytes_per_row as u32)
364                            .unwrap()
365                            .into(),
366                    ),
367                    rows_per_image: None,
368                },
369            },
370            src_image.texture_descriptor.size,
371        );
372
373        render_queue.submit(std::iter::once(encoder.finish()));
374    }
375}
376
377/// runs in render world after Render stage to send image from buffer via channel (receiver is in main world)
378fn receive_image_from_buffer(
379    image_copiers: Res<ImageCopiers>,
380    render_device: Res<RenderDevice>,
381    sender: Res<RenderWorldSender>,
382) {
383    for image_copier in image_copiers.0.iter() {
384        if !image_copier.enabled() {
385            continue;
386        }
387
388        // Finally time to get our data back from the gpu.
389        // First we get a buffer slice which represents a chunk of the buffer (which we
390        // can't access yet).
391        // We want the whole thing so use unbounded range.
392        let buffer_slice = image_copier.buffer.slice(..);
393
394        // Now things get complicated. WebGPU, for safety reasons, only allows either the GPU
395        // or CPU to access a buffer's contents at a time. We need to "map" the buffer which means
396        // flipping ownership of the buffer over to the CPU and making access legal. We do this
397        // with `BufferSlice::map_async`.
398        //
399        // The problem is that map_async is not an async function so we can't await it. What
400        // we need to do instead is pass in a closure that will be executed when the slice is
401        // either mapped or the mapping has failed.
402        //
403        // The problem with this is that we don't have a reliable way to wait in the main
404        // code for the buffer to be mapped and even worse, calling get_mapped_range or
405        // get_mapped_range_mut prematurely will cause a panic, not return an error.
406        //
407        // Using channels solves this as awaiting the receiving of a message from
408        // the passed closure will force the outside code to wait. It also doesn't hurt
409        // if the closure finishes before the outside code catches up as the message is
410        // buffered and receiving will just pick that up.
411        //
412        // It may also be worth noting that although on native, the usage of asynchronous
413        // channels is wholly unnecessary, for the sake of portability to Wasm
414        // we'll use async channels that work on both native and Wasm.
415
416        let (s, r) = crossbeam_channel::bounded(1);
417
418        // Maps the buffer so it can be read on the cpu
419        buffer_slice.map_async(MapMode::Read, move |r| match r {
420            // This will execute once the gpu is ready, so after the call to poll()
421            Ok(r) => s.send(r).expect("Failed to send map update"),
422            Err(err) => panic!("Failed to map buffer {err}"),
423        });
424
425        // In order for the mapping to be completed, one of three things must happen.
426        // One of those can be calling `Device::poll`. This isn't necessary on the web as devices
427        // are polled automatically but natively, we need to make sure this happens manually.
428        // `Maintain::Wait` will cause the thread to wait on native but not on WebGpu.
429
430        // This blocks until the gpu is done executing everything
431        render_device
432            .poll(PollType::wait_indefinitely())
433            .expect("Failed to poll device for map async");
434
435        // This blocks until the buffer is mapped
436        r.recv().expect("Failed to receive the map_async message");
437
438        // This could fail on app exit, if Main world clears resources (including receiver) while Render world still renders
439        let _ = sender.send(buffer_slice.get_mapped_range().unwrap().to_vec());
440
441        // We need to make sure all `BufferView`'s are dropped before we do what we're about
442        // to do.
443        // Unmap so that we can copy to the staging buffer in the next iteration.
444        image_copier.buffer.unmap();
445    }
446}
447
448/// CPU-side image for saving
449#[derive(Component, Deref, DerefMut)]
450struct ImageToSave(Handle<Image>);
451
452// Takes from channel image content sent from render world and saves it to disk
453fn update(
454    images_to_save: Query<&ImageToSave>,
455    receiver: Res<MainWorldReceiver>,
456    mut images: ResMut<Assets<Image>>,
457    mut scene_controller: ResMut<SceneController>,
458    mut app_exit_writer: MessageWriter<AppExit>,
459    mut file_number: Local<u32>,
460) {
461    if let SceneState::Render(n) = scene_controller.state {
462        if n < 1 {
463            // We don't want to block the main world on this,
464            // so we use try_recv which attempts to receive without blocking
465            let mut image_data = Vec::new();
466            while let Ok(data) = receiver.try_recv() {
467                // image generation could be faster than saving to fs,
468                // that's why use only last of them
469                image_data = data;
470            }
471            if !image_data.is_empty() {
472                for image in images_to_save.iter() {
473                    // Fill correct data from channel to image
474                    let mut img_bytes = images.get_mut(image.id()).unwrap();
475
476                    // We need to ensure that this works regardless of the image dimensions
477                    // If the image became wider when copying from the texture to the buffer,
478                    // then the data is reduced to its original size when copying from the buffer to the image.
479                    let row_bytes = img_bytes.width() as usize
480                        * img_bytes.texture_descriptor.format.pixel_size().unwrap();
481                    let aligned_row_bytes = RenderDevice::align_copy_bytes_per_row(row_bytes);
482                    if row_bytes == aligned_row_bytes {
483                        img_bytes.data.as_mut().unwrap().clone_from(&image_data);
484                    } else {
485                        // shrink data to original image size
486                        img_bytes.data = Some(
487                            image_data
488                                .chunks(aligned_row_bytes)
489                                .take(img_bytes.height() as usize)
490                                .flat_map(|row| &row[..row_bytes.min(row.len())])
491                                .cloned()
492                                .collect(),
493                        );
494                    }
495
496                    // Create RGBA Image Buffer
497                    let img = match img_bytes.clone().try_into_dynamic() {
498                        Ok(img) => img.to_rgba8(),
499                        Err(e) => panic!("Failed to create image buffer {e:?}"),
500                    };
501
502                    // Prepare directory for images, test_images in bevy folder is used here for example
503                    // You should choose the path depending on your needs
504                    let images_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test_images");
505                    info!("Saving image to: {images_dir:?}");
506                    std::fs::create_dir_all(&images_dir).unwrap();
507
508                    // Choose filename starting from 000.png
509                    let image_path = images_dir.join(format!("{:03}.png", file_number.deref()));
510                    *file_number.deref_mut() += 1;
511
512                    // Finally saving image to file, this heavy blocking operation is kept here
513                    // for example simplicity, but in real app you should move it to a separate task
514                    if let Err(e) = img.save(image_path) {
515                        panic!("Failed to save image: {e}");
516                    };
517                }
518                if scene_controller.single_image {
519                    app_exit_writer.write(AppExit::Success);
520                }
521            }
522        } else {
523            // clears channel for skipped frames
524            while receiver.try_recv().is_ok() {}
525            scene_controller.state = SceneState::Render(n - 1);
526        }
527    }
528}
examples/stress_tests/many_animated_sprites.rs (line 139)
135fn print_sprite_count(time: Res<Time>, mut timer: Local<PrintingTimer>, sprites: Query<&Sprite>) {
136    timer.tick(time.delta());
137
138    if timer.just_finished() {
139        info!("Sprites: {}", sprites.iter().count());
140    }
141}
examples/stress_tests/many_sprites.rs (line 123)
119fn print_sprite_count(time: Res<Time>, mut timer: Local<PrintingTimer>, sprites: Query<&Sprite>) {
120    timer.tick(time.delta());
121
122    if timer.just_finished() {
123        info!("Sprites: {}", sprites.iter().count());
124    }
125}
Source

pub fn iter_mut(&mut self) -> QueryIter<'_, 's, D, F> ⓘ

Returns an Iterator over the query items.

This iterator is always guaranteed to return results from each matching entity once and only once. Iteration order is not guaranteed.

If the QueryData does not implement IterQueryData, then it is not sound to yield multiple items concurrently and the resulting QueryIter will not implement Iterator. To iterate over the items in that case, use the QueryIter::fetch_next() method, which ensures only one item is alive at a time.

§Example

Here, the gravity_system updates the Velocity component of every entity that contains it:

fn gravity_system(mut query: Query<&mut Velocity>) {
    const DELTA: f32 = 1.0 / 60.0;
    for mut velocity in &mut query {
        velocity.y -= 9.8 * DELTA;
    }
}
§See also

iter for read-only query items.

Examples found in repository?
examples/3d/irradiance_volumes.rs (line 305)
304fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
305    for mut text in text_query.iter_mut() {
306        *text = app_status.create_text();
307    }
308}
309
310impl AppStatus {
311    // Constructs the help text at the bottom of the screen based on the
312    // application status.
313    fn create_text(&self) -> Text {
314        let irradiance_volume_help_text = if self.irradiance_volume_present {
315            DISABLE_IRRADIANCE_VOLUME_HELP_TEXT
316        } else {
317            ENABLE_IRRADIANCE_VOLUME_HELP_TEXT
318        };
319
320        let voxels_help_text = if self.voxels_visible {
321            HIDE_VOXELS_HELP_TEXT
322        } else {
323            SHOW_VOXELS_HELP_TEXT
324        };
325
326        let rotation_help_text = if self.rotating {
327            STOP_ROTATION_HELP_TEXT
328        } else {
329            START_ROTATION_HELP_TEXT
330        };
331
332        let switch_mesh_help_text = match self.model {
333            ExampleModel::Sphere => SWITCH_TO_FOX_HELP_TEXT,
334            ExampleModel::Fox => SWITCH_TO_SPHERE_HELP_TEXT,
335        };
336
337        format!(
338            "{CLICK_TO_MOVE_HELP_TEXT}\n\
339            {voxels_help_text}\n\
340            {irradiance_volume_help_text}\n\
341            {rotation_help_text}\n\
342            {switch_mesh_help_text}"
343        )
344        .into()
345    }
346}
347
348// Rotates the camera a bit every frame.
349fn rotate_camera(
350    mut camera_query: Query<&mut Transform, With<Camera3d>>,
351    time: Res<Time>,
352    app_status: Res<AppStatus>,
353) {
354    if !app_status.rotating {
355        return;
356    }
357
358    for mut transform in camera_query.iter_mut() {
359        transform.translation = Vec2::from_angle(ROTATION_SPEED * time.delta_secs())
360            .rotate(transform.translation.xz())
361            .extend(transform.translation.y)
362            .xzy();
363        transform.look_at(Vec3::ZERO, Vec3::Y);
364    }
365}
366
367// Toggles between the unskinned sphere model and the skinned fox model if the
368// user requests it.
369fn change_main_object(
370    keyboard: Res<ButtonInput<KeyCode>>,
371    mut app_status: ResMut<AppStatus>,
372    mut sphere_query: Query<
373        &mut Visibility,
374        (With<MainObject>, With<Mesh3d>, Without<WorldAssetRoot>),
375    >,
376    mut fox_query: Query<&mut Visibility, (With<MainObject>, With<WorldAssetRoot>)>,
377) {
378    if !keyboard.just_pressed(KeyCode::Tab) {
379        return;
380    }
381    let Some(mut sphere_visibility) = sphere_query.iter_mut().next() else {
382        return;
383    };
384    let Some(mut fox_visibility) = fox_query.iter_mut().next() else {
385        return;
386    };
387
388    match app_status.model {
389        ExampleModel::Sphere => {
390            *sphere_visibility = Visibility::Hidden;
391            *fox_visibility = Visibility::Visible;
392            app_status.model = ExampleModel::Fox;
393        }
394        ExampleModel::Fox => {
395            *sphere_visibility = Visibility::Visible;
396            *fox_visibility = Visibility::Hidden;
397            app_status.model = ExampleModel::Sphere;
398        }
399    }
400}
401
402impl Default for AppStatus {
403    fn default() -> Self {
404        Self {
405            irradiance_volume_present: true,
406            rotating: true,
407            model: ExampleModel::Sphere,
408            voxels_visible: false,
409        }
410    }
411}
412
413// Turns on and off the irradiance volume as requested by the user.
414fn toggle_irradiance_volumes(
415    mut commands: Commands,
416    keyboard: Res<ButtonInput<KeyCode>>,
417    light_probe_query: Query<Entity, With<LightProbe>>,
418    mut app_status: ResMut<AppStatus>,
419    assets: Res<ExampleAssets>,
420    mut ambient_light: ResMut<GlobalAmbientLight>,
421) {
422    if !keyboard.just_pressed(KeyCode::Space) {
423        return;
424    };
425
426    let Some(light_probe) = light_probe_query.iter().next() else {
427        return;
428    };
429
430    if app_status.irradiance_volume_present {
431        commands.entity(light_probe).remove::<IrradianceVolume>();
432        ambient_light.brightness = AMBIENT_LIGHT_BRIGHTNESS * IRRADIANCE_VOLUME_INTENSITY;
433        app_status.irradiance_volume_present = false;
434    } else {
435        commands.entity(light_probe).insert(IrradianceVolume {
436            voxels: assets.irradiance_volume.clone(),
437            intensity: IRRADIANCE_VOLUME_INTENSITY,
438            ..default()
439        });
440        ambient_light.brightness = 0.0;
441        app_status.irradiance_volume_present = true;
442    }
443}
444
445fn toggle_rotation(keyboard: Res<ButtonInput<KeyCode>>, mut app_status: ResMut<AppStatus>) {
446    if keyboard.just_pressed(KeyCode::Enter) {
447        app_status.rotating = !app_status.rotating;
448    }
449}
450
451// Handles clicks on the plane that reposition the object.
452fn handle_mouse_clicks(
453    buttons: Res<ButtonInput<MouseButton>>,
454    windows: Query<&Window, With<PrimaryWindow>>,
455    cameras: Query<(&Camera, &GlobalTransform)>,
456    mut main_objects: Query<&mut Transform, With<MainObject>>,
457) {
458    if !buttons.pressed(MouseButton::Left) {
459        return;
460    }
461    let Some(mouse_position) = windows.iter().next().and_then(Window::cursor_position) else {
462        return;
463    };
464    let Some((camera, camera_transform)) = cameras.iter().next() else {
465        return;
466    };
467
468    // Figure out where the user clicked on the plane.
469    let Ok(ray) = camera.viewport_to_world(camera_transform, mouse_position) else {
470        return;
471    };
472    let Some(plane_intersection) =
473        ray.plane_intersection_point(Vec3::ZERO, InfinitePlane3d::new(Vec3::Y))
474    else {
475        return;
476    };
477    // Move all the main objects.
478    for mut transform in main_objects.iter_mut() {
479        transform.translation = vec3(
480            plane_intersection.x,
481            transform.translation.y,
482            plane_intersection.z,
483        );
484    }
485}
486
487impl FromWorld for ExampleAssets {
488    fn from_world(world: &mut World) -> Self {
489        let fox_animation =
490            world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
491        let (fox_animation_graph, fox_animation_node) =
492            AnimationGraph::from_clip(fox_animation.clone());
493
494        ExampleAssets {
495            main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
496            fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
497            main_sphere_material: world.add_asset(Color::from(SILVER)),
498            main_scene: world.load_asset(
499                GltfAssetLabel::Scene(0)
500                    .from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
501            ),
502            irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
503            fox_animation_graph: world.add_asset(fox_animation_graph),
504            fox_animation_node,
505            voxel_cube: world.add_asset(Cuboid::default()),
506            // Just use a specular map for the skybox since it's not too blurry.
507            // In reality you wouldn't do this--you'd use a real skybox texture--but
508            // reusing the textures like this saves space in the Bevy repository.
509            skybox: world.load_asset("environment_maps/pisa_specular_rgb9e5_zstd.ktx2"),
510        }
511    }
512}
513
514// Plays the animation on the fox.
515fn play_animations(
516    mut commands: Commands,
517    assets: Res<ExampleAssets>,
518    mut players: Query<(Entity, &mut AnimationPlayer), Without<AnimationGraphHandle>>,
519) {
520    for (entity, mut player) in players.iter_mut() {
521        commands
522            .entity(entity)
523            .insert(AnimationGraphHandle(assets.fox_animation_graph.clone()));
524        player.play(assets.fox_animation_node).repeat();
525    }
526}
527
528fn create_cubes(
529    image_assets: Res<Assets<Image>>,
530    mut commands: Commands,
531    irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
532    voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
533    voxel_cubes: Query<Entity, With<VoxelCube>>,
534    example_assets: Res<ExampleAssets>,
535    mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
536) {
537    // If voxel cubes have already been spawned, don't do anything.
538    if !voxel_cubes.is_empty() {
539        return;
540    }
541
542    let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
543        return;
544    };
545
546    for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
547        let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
548            continue;
549        };
550
551        let resolution = image.texture_descriptor.size;
552
553        let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
554            base: StandardMaterial::from(Color::from(RED)),
555            extension: VoxelVisualizationExtension {
556                irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
557                    world_from_voxel: VOXEL_FROM_WORLD.inverse(),
558                    voxel_from_world: VOXEL_FROM_WORLD,
559                    resolution: uvec3(
560                        resolution.width,
561                        resolution.height,
562                        resolution.depth_or_array_layers,
563                    ),
564                    intensity: IRRADIANCE_VOLUME_INTENSITY,
565                },
566            },
567        });
568
569        let scale = vec3(
570            1.0 / resolution.width as f32,
571            1.0 / resolution.height as f32,
572            1.0 / resolution.depth_or_array_layers as f32,
573        );
574
575        // Spawn a cube for each voxel.
576        for z in 0..resolution.depth_or_array_layers {
577            for y in 0..resolution.height {
578                for x in 0..resolution.width {
579                    let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
580                    let pos = global_transform.transform_point(uvw);
581                    let voxel_cube = commands
582                        .spawn((
583                            Mesh3d(example_assets.voxel_cube.clone()),
584                            MeshMaterial3d(voxel_cube_material.clone()),
585                            Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
586                                .with_translation(pos),
587                        ))
588                        .insert(VoxelCube)
589                        .insert(NotShadowCaster)
590                        .id();
591
592                    commands.entity(voxel_cube_parent).add_child(voxel_cube);
593                }
594            }
595        }
596    }
597}
598
599// Draws a gizmo showing the bounds of the irradiance volume.
600fn draw_gizmo(
601    mut gizmos: Gizmos,
602    irradiance_volume_query: Query<&GlobalTransform, With<IrradianceVolume>>,
603    app_status: Res<AppStatus>,
604) {
605    if app_status.voxels_visible {
606        for transform in irradiance_volume_query.iter() {
607            gizmos.cube(*transform, GIZMO_COLOR);
608        }
609    }
610}
611
612// Handles a request from the user to toggle the voxel visibility on and off.
613fn toggle_voxel_visibility(
614    keyboard: Res<ButtonInput<KeyCode>>,
615    mut app_status: ResMut<AppStatus>,
616    mut voxel_cube_parent_query: Query<&mut Visibility, With<VoxelCubeParent>>,
617) {
618    if !keyboard.just_pressed(KeyCode::Backspace) {
619        return;
620    }
621
622    app_status.voxels_visible = !app_status.voxels_visible;
623
624    for mut visibility in voxel_cube_parent_query.iter_mut() {
625        *visibility = if app_status.voxels_visible {
626            Visibility::Visible
627        } else {
628            Visibility::Hidden
629        };
630    }
631}
More examples
Hide additional examples
examples/3d/reflection_probes.rs (line 281)
280fn update_text(mut text_query: Query<&mut Text>, app_status: Res<AppStatus>) {
281    for mut text in text_query.iter_mut() {
282        *text = app_status.create_text();
283    }
284}
285
286impl TryFrom<u32> for ReflectionMode {
287    type Error = ();
288
289    fn try_from(value: u32) -> Result<Self, Self::Error> {
290        match value {
291            0 => Ok(ReflectionMode::EnvironmentMap),
292            1 => Ok(ReflectionMode::ReflectionProbe),
293            2 => Ok(ReflectionMode::GeneratedEnvironmentMap),
294            _ => Err(()),
295        }
296    }
297}
298
299impl Display for ReflectionMode {
300    fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
301        let text = match *self {
302            ReflectionMode::EnvironmentMap => "Environment map",
303            ReflectionMode::ReflectionProbe => "Reflection probe",
304            ReflectionMode::GeneratedEnvironmentMap => "Generated environment map",
305        };
306        formatter.write_str(text)
307    }
308}
309
310impl AppStatus {
311    // Constructs the help text at the bottom of the screen based on the
312    // application status.
313    fn create_text(&self) -> Text {
314        let rotation_help_text = if self.rotating {
315            STOP_ROTATION_HELP_TEXT
316        } else {
317            START_ROTATION_HELP_TEXT
318        };
319
320        format!(
321            "{}\n{}\nRoughness: {:.2}\n{}\nUp/Down arrows to change roughness",
322            self.reflection_mode,
323            rotation_help_text,
324            self.sphere_roughness,
325            REFLECTION_MODE_HELP_TEXT
326        )
327        .into()
328    }
329}
330
331// Creates the world environment map light, used as a fallback if no reflection
332// probe is applicable to a mesh.
333fn create_camera_environment_map_light(cubemaps: &Cubemaps) -> EnvironmentMapLight {
334    EnvironmentMapLight {
335        diffuse_map: cubemaps.diffuse_environment_map.clone(),
336        specular_map: cubemaps.specular_environment_map.clone(),
337        intensity: ENV_MAP_INTENSITY,
338        ..default()
339    }
340}
341
342// Rotates the camera a bit every frame.
343fn rotate_camera(
344    time: Res<Time>,
345    mut camera_query: Query<&mut Transform, With<Camera3d>>,
346    app_status: Res<AppStatus>,
347) {
348    if !app_status.rotating {
349        return;
350    }
351
352    for mut transform in camera_query.iter_mut() {
353        transform.translation = Vec2::from_angle(time.delta_secs() * PI / 5.0)
354            .rotate(transform.translation.xz())
355            .extend(transform.translation.y)
356            .xzy();
357        transform.look_at(Vec3::ZERO, Vec3::Y);
358    }
359}
examples/math/bounding_2d.rs (line 40)
39fn spin(time: Res<Time>, mut query: Query<&mut Transform, With<Spin>>) {
40    for mut transform in query.iter_mut() {
41        transform.rotation *= Quat::from_rotation_z(time.delta_secs() / 5.);
42    }
43}
44
45#[derive(States, Default, Debug, Hash, PartialEq, Eq, Clone, Copy)]
46enum Test {
47    AabbSweep,
48    CircleSweep,
49    #[default]
50    RayCast,
51    AabbCast,
52    CircleCast,
53}
54
55fn update_test_state(
56    keycode: Res<ButtonInput<KeyCode>>,
57    cur_state: Res<State<Test>>,
58    mut state: ResMut<NextState<Test>>,
59) {
60    if !keycode.just_pressed(KeyCode::Space) {
61        return;
62    }
63
64    use Test::*;
65    let next = match **cur_state {
66        AabbSweep => CircleSweep,
67        CircleSweep => RayCast,
68        RayCast => AabbCast,
69        AabbCast => CircleCast,
70        CircleCast => AabbSweep,
71    };
72    state.set(next);
73}
74
75fn update_text(mut text: Single<&mut Text>, cur_state: Res<State<Test>>) {
76    if !cur_state.is_changed() {
77        return;
78    }
79
80    text.clear();
81
82    text.push_str("Intersection test:\n");
83    use Test::*;
84    for &test in &[AabbSweep, CircleSweep, RayCast, AabbCast, CircleCast] {
85        let s = if **cur_state == test { "*" } else { " " };
86        text.push_str(&format!(" {s} {test:?} {s}\n"));
87    }
88    text.push_str("\nPress space to cycle");
89}
90
91#[derive(Component)]
92enum Shape {
93    Rectangle(Rectangle),
94    Circle(Circle),
95    Triangle(Triangle2d),
96    Line(Segment2d),
97    Capsule(Capsule2d),
98    Polygon(RegularPolygon),
99}
100
101fn render_shapes(mut gizmos: Gizmos, query: Query<(&Shape, &Transform)>) {
102    let color = GRAY;
103    for (shape, transform) in query.iter() {
104        let translation = transform.translation.xy();
105        let rotation = transform.rotation.to_euler(EulerRot::YXZ).2;
106        let isometry = Isometry2d::new(translation, Rot2::radians(rotation));
107        match shape {
108            Shape::Rectangle(r) => {
109                gizmos.primitive_2d(r, isometry, color);
110            }
111            Shape::Circle(c) => {
112                gizmos.primitive_2d(c, isometry, color);
113            }
114            Shape::Triangle(t) => {
115                gizmos.primitive_2d(t, isometry, color);
116            }
117            Shape::Line(l) => {
118                gizmos.primitive_2d(l, isometry, color);
119            }
120            Shape::Capsule(c) => {
121                gizmos.primitive_2d(c, isometry, color);
122            }
123            Shape::Polygon(p) => {
124                gizmos.primitive_2d(p, isometry, color);
125            }
126        }
127    }
128}
129
130#[derive(Component)]
131enum DesiredVolume {
132    Aabb,
133    Circle,
134}
135
136#[derive(Component, Debug)]
137enum CurrentVolume {
138    Aabb(Aabb2d),
139    Circle(BoundingCircle),
140}
141
142fn update_volumes(
143    mut commands: Commands,
144    query: Query<
145        (Entity, &DesiredVolume, &Shape, &Transform),
146        Or<(Changed<DesiredVolume>, Changed<Shape>, Changed<Transform>)>,
147    >,
148) {
149    for (entity, desired_volume, shape, transform) in query.iter() {
150        let translation = transform.translation.xy();
151        let rotation = transform.rotation.to_euler(EulerRot::YXZ).2;
152        let isometry = Isometry2d::new(translation, Rot2::radians(rotation));
153        match desired_volume {
154            DesiredVolume::Aabb => {
155                let aabb = match shape {
156                    Shape::Rectangle(r) => r.aabb_2d(isometry),
157                    Shape::Circle(c) => c.aabb_2d(isometry),
158                    Shape::Triangle(t) => t.aabb_2d(isometry),
159                    Shape::Line(l) => l.aabb_2d(isometry),
160                    Shape::Capsule(c) => c.aabb_2d(isometry),
161                    Shape::Polygon(p) => p.aabb_2d(isometry),
162                };
163                commands.entity(entity).insert(CurrentVolume::Aabb(aabb));
164            }
165            DesiredVolume::Circle => {
166                let circle = match shape {
167                    Shape::Rectangle(r) => r.bounding_circle(isometry),
168                    Shape::Circle(c) => c.bounding_circle(isometry),
169                    Shape::Triangle(t) => t.bounding_circle(isometry),
170                    Shape::Line(l) => l.bounding_circle(isometry),
171                    Shape::Capsule(c) => c.bounding_circle(isometry),
172                    Shape::Polygon(p) => p.bounding_circle(isometry),
173                };
174                commands
175                    .entity(entity)
176                    .insert(CurrentVolume::Circle(circle));
177            }
178        }
179    }
180}
181
182fn render_volumes(mut gizmos: Gizmos, query: Query<(&CurrentVolume, &Intersects)>) {
183    for (volume, intersects) in query.iter() {
184        let color = if **intersects { AQUA } else { ORANGE_RED };
185        match volume {
186            CurrentVolume::Aabb(a) => {
187                gizmos.rect_2d(a.center(), a.half_size() * 2., color);
188            }
189            CurrentVolume::Circle(c) => {
190                gizmos.circle_2d(c.center(), c.radius(), color);
191            }
192        }
193    }
194}
195
196#[derive(Component, Deref, DerefMut, Default)]
197struct Intersects(bool);
198
199const OFFSET_X: f32 = 125.;
200const OFFSET_Y: f32 = 75.;
201
202fn setup(mut commands: Commands) {
203    commands.spawn(Camera2d);
204
205    commands.spawn((
206        Transform::from_xyz(-OFFSET_X, OFFSET_Y, 0.),
207        Shape::Circle(Circle::new(45.)),
208        DesiredVolume::Aabb,
209        Intersects::default(),
210    ));
211
212    commands.spawn((
213        Transform::from_xyz(0., OFFSET_Y, 0.),
214        Shape::Rectangle(Rectangle::new(80., 80.)),
215        Spin,
216        DesiredVolume::Circle,
217        Intersects::default(),
218    ));
219
220    commands.spawn((
221        Transform::from_xyz(OFFSET_X, OFFSET_Y, 0.),
222        Shape::Triangle(Triangle2d::new(
223            Vec2::new(-40., -40.),
224            Vec2::new(-20., 40.),
225            Vec2::new(40., 50.),
226        )),
227        Spin,
228        DesiredVolume::Aabb,
229        Intersects::default(),
230    ));
231
232    commands.spawn((
233        Transform::from_xyz(-OFFSET_X, -OFFSET_Y, 0.),
234        Shape::Line(Segment2d::from_direction_and_length(
235            Dir2::from_xy(1., 0.3).unwrap(),
236            90.,
237        )),
238        Spin,
239        DesiredVolume::Circle,
240        Intersects::default(),
241    ));
242
243    commands.spawn((
244        Transform::from_xyz(0., -OFFSET_Y, 0.),
245        Shape::Capsule(Capsule2d::new(25., 50.)),
246        Spin,
247        DesiredVolume::Aabb,
248        Intersects::default(),
249    ));
250
251    commands.spawn((
252        Transform::from_xyz(OFFSET_X, -OFFSET_Y, 0.),
253        Shape::Polygon(RegularPolygon::new(50., 6)),
254        Spin,
255        DesiredVolume::Circle,
256        Intersects::default(),
257    ));
258
259    commands.spawn((
260        Text::default(),
261        Node {
262            position_type: PositionType::Absolute,
263            top: px(12),
264            left: px(12),
265            ..default()
266        },
267    ));
268}
269
270fn draw_filled_circle(gizmos: &mut Gizmos, position: Vec2, color: Srgba) {
271    for r in [1., 2., 3.] {
272        gizmos.circle_2d(position, r, color);
273    }
274}
275
276fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) {
277    gizmos.line_2d(
278        ray.ray.origin,
279        ray.ray.origin + *ray.ray.direction * ray.max,
280        WHITE,
281    );
282    draw_filled_circle(gizmos, ray.ray.origin, FUCHSIA);
283}
284
285fn get_and_draw_ray(gizmos: &mut Gizmos, time: &Time) -> RayCast2d {
286    let ray = Vec2::new(ops::cos(time.elapsed_secs()), ops::sin(time.elapsed_secs()));
287    let dist = 150. + ops::sin(0.5 * time.elapsed_secs()).abs() * 500.;
288
289    let aabb_ray = Ray2d {
290        origin: ray * 250.,
291        direction: Dir2::new_unchecked(-ray),
292    };
293    let ray_cast = RayCast2d::from_ray(aabb_ray, dist - 20.);
294
295    draw_ray(gizmos, &ray_cast);
296    ray_cast
297}
298
299fn ray_cast_system(
300    mut gizmos: Gizmos,
301    time: Res<Time>,
302    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
303) {
304    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
305
306    for (volume, mut intersects) in volumes.iter_mut() {
307        let toi = match volume {
308            CurrentVolume::Aabb(a) => ray_cast.aabb_intersection_at(a),
309            CurrentVolume::Circle(c) => ray_cast.circle_intersection_at(c),
310        };
311        **intersects = toi.is_some();
312        if let Some(toi) = toi {
313            draw_filled_circle(
314                &mut gizmos,
315                ray_cast.ray.origin + *ray_cast.ray.direction * toi,
316                LIME,
317            );
318        }
319    }
320}
321
322fn aabb_cast_system(
323    mut gizmos: Gizmos,
324    time: Res<Time>,
325    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
326) {
327    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
328    let aabb_cast = AabbCast2d {
329        aabb: Aabb2d::new(Vec2::ZERO, Vec2::splat(15.)),
330        ray: ray_cast,
331    };
332
333    for (volume, mut intersects) in volumes.iter_mut() {
334        let toi = match *volume {
335            CurrentVolume::Aabb(a) => aabb_cast.aabb_collision_at(a),
336            CurrentVolume::Circle(_) => None,
337        };
338
339        **intersects = toi.is_some();
340        if let Some(toi) = toi {
341            gizmos.rect_2d(
342                aabb_cast.ray.ray.origin + *aabb_cast.ray.ray.direction * toi,
343                aabb_cast.aabb.half_size() * 2.,
344                LIME,
345            );
346        }
347    }
348}
349
350fn bounding_circle_cast_system(
351    mut gizmos: Gizmos,
352    time: Res<Time>,
353    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
354) {
355    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
356    let circle_cast = BoundingCircleCast {
357        circle: BoundingCircle::new(Vec2::ZERO, 15.),
358        ray: ray_cast,
359    };
360
361    for (volume, mut intersects) in volumes.iter_mut() {
362        let toi = match *volume {
363            CurrentVolume::Aabb(_) => None,
364            CurrentVolume::Circle(c) => circle_cast.circle_collision_at(c),
365        };
366
367        **intersects = toi.is_some();
368        if let Some(toi) = toi {
369            gizmos.circle_2d(
370                circle_cast.ray.ray.origin + *circle_cast.ray.ray.direction * toi,
371                circle_cast.circle.radius(),
372                LIME,
373            );
374        }
375    }
376}
377
378fn get_intersection_position(time: &Time) -> Vec2 {
379    let x = ops::cos(0.8 * time.elapsed_secs()) * 250.;
380    let y = ops::sin(0.4 * time.elapsed_secs()) * 100.;
381    Vec2::new(x, y)
382}
383
384fn aabb_intersection_system(
385    mut gizmos: Gizmos,
386    time: Res<Time>,
387    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
388) {
389    let center = get_intersection_position(&time);
390    let aabb = Aabb2d::new(center, Vec2::splat(50.));
391    gizmos.rect_2d(center, aabb.half_size() * 2., YELLOW);
392
393    for (volume, mut intersects) in volumes.iter_mut() {
394        let hit = match volume {
395            CurrentVolume::Aabb(a) => aabb.intersects(a),
396            CurrentVolume::Circle(c) => aabb.intersects(c),
397        };
398
399        **intersects = hit;
400    }
401}
402
403fn circle_intersection_system(
404    mut gizmos: Gizmos,
405    time: Res<Time>,
406    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
407) {
408    let center = get_intersection_position(&time);
409    let circle = BoundingCircle::new(center, 50.);
410    gizmos.circle_2d(center, circle.radius(), YELLOW);
411
412    for (volume, mut intersects) in volumes.iter_mut() {
413        let hit = match volume {
414            CurrentVolume::Aabb(a) => circle.intersects(a),
415            CurrentVolume::Circle(c) => circle.intersects(c),
416        };
417
418        **intersects = hit;
419    }
420}
examples/3d/scrolling_fog.rs (line 123)
122fn scroll_fog(time: Res<Time>, mut query: Query<&mut FogVolume>) {
123    for mut fog_volume in query.iter_mut() {
124        fog_volume.density_texture_offset += Vec3::new(0.0, 0.0, 0.04) * time.delta_secs();
125    }
126}
examples/ui/scroll_and_overflow/overflow_transform.rs (line 142)
141fn scale_inner(time: Res<Time>, mut query: Query<&mut UiTransform, With<InnerNode>>) {
142    for mut transform in query.iter_mut() {
143        transform.scale = Vec2::splat(1. + 0.75 * sin(0.4 * time.elapsed_secs()));
144    }
145}
examples/stress_tests/many_cameras_lights.rs (line 107)
106fn rotate_cameras(time: Res<Time>, mut query: Query<&mut Transform, With<Camera>>) {
107    for mut transform in query.iter_mut() {
108        transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(time.delta_secs()));
109    }
110}
Source

pub fn iter_inner(self) -> QueryIter<'w, 's, D, F> ⓘ

Returns an Iterator over the query items, with the actual “inner” world lifetime.

This iterator is always guaranteed to return results from each matching entity once and only once. Iteration order is not guaranteed.

If the QueryData does not implement IterQueryData, then it is not sound to yield multiple items concurrently and the resulting QueryIter will not implement Iterator. To iterate over the items in that case, use the QueryIter::fetch_next() method, which ensures only one item is alive at a time.

§Example

Here, the report_names_system iterates over the Player component of every entity that contains it:

fn report_names_system(query: Query<&Player>) {
    for player in &query {
        println!("Say hello to {}!", player.name);
    }
}
Source

pub fn iter_combinations<const K: usize>( &self, ) -> QueryCombinationIter<'_, 's, <D as QueryData>::ReadOnly, F, K> ⓘ

Returns a QueryCombinationIter over all combinations of K read-only query items without repetition.

This iterator is always guaranteed to return results from each unique pair of matching entities. Iteration order is not guaranteed.

§Example
fn some_system(query: Query<&ComponentA>) {
    for [a1, a2] in query.iter_combinations() {
        // ...
    }
}
§See also
Source

pub fn iter_combinations_mut<const K: usize>( &mut self, ) -> QueryCombinationIter<'_, 's, D, F, K> ⓘ
where D: IterQueryData,

Returns a QueryCombinationIter over all combinations of K query items without repetition.

This iterator is always guaranteed to return results from each unique pair of matching entities. Iteration order is not guaranteed.

§Example
fn some_system(mut query: Query<&mut ComponentA>) {
    let mut combinations = query.iter_combinations_mut();
    while let Some([mut a1, mut a2]) = combinations.fetch_next() {
        // mutably access components data
    }
}
§See also
Examples found in repository?
examples/ecs/iter_combinations.rs (line 123)
122fn interact_bodies(mut query: Query<(&Mass, &GlobalTransform, &mut Acceleration)>) {
123    let mut iter = query.iter_combinations_mut();
124    while let Some([(Mass(m1), transform1, mut acc1), (Mass(m2), transform2, mut acc2)]) =
125        iter.fetch_next()
126    {
127        let delta = transform2.translation() - transform1.translation();
128        let distance_sq: f32 = delta.length_squared();
129
130        let f = GRAVITY_CONSTANT / distance_sq;
131        let force_unit_mass = delta * f;
132        acc1.0 += force_unit_mass * *m2;
133        acc2.0 -= force_unit_mass * *m1;
134    }
135}
Source

pub fn iter_combinations_inner<const K: usize>( self, ) -> QueryCombinationIter<'w, 's, D, F, K> ⓘ
where D: IterQueryData,

Returns a QueryCombinationIter over all combinations of K query items without repetition. This consumes the Query to return results with the actual “inner” world lifetime.

This iterator is always guaranteed to return results from each unique pair of matching entities. Iteration order is not guaranteed.

§Example
fn some_system(query: Query<&mut ComponentA>) {
    let mut combinations = query.iter_combinations_inner();
    while let Some([mut a1, mut a2]) = combinations.fetch_next() {
        // mutably access components data
    }
}
§See also
Source

pub fn iter_many<EntityList>( &self, entities: EntityList, ) -> QueryManyIter<'_, 's, <D as QueryData>::ReadOnly, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: IntoIterator, <EntityList as IntoIterator>::Item: EntityEquivalent,

Returns an Iterator over the read-only query items generated from an Entity list.

Items are returned in the order of the list of entities, and may not be unique if the input doesn’t guarantee uniqueness. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Examples
// A component containing an entity list.
#[derive(Component)]
struct Friends {
    list: Vec<Entity>,
}

fn matching_system(
    friends_query: Query<&Friends>,
    counter_query: Query<&Counter>,
) {
    for friends in &friends_query {
        for counter in counter_query.iter_many(&friends.list).matched() {
            println!("Friend's counter: {}", counter.value);
        }
    }
}

fn unwrapping_system(
    friends_query: Query<&Friends>,
    counter_query: Query<&Counter>,
) {
    for friends in &friends_query {
        for counter in counter_query.iter_many(&friends.list).unwrapped() {
            println!("Friend's counter: {}", counter.value);
        }
    }
}

fn error_system(
    friends_query: Query<&Friends>,
    counter_query: Query<&Counter>,
) -> Result<(), BevyError> {
    for friends in &friends_query {
        for counter_result in counter_query.iter_many(&friends.list) {
            let counter = counter_result?;
            println!("Friend's counter: {}", counter.value);
        }
    }
    Ok(())
}
§See also
Examples found in repository?
examples/3d/order_independent_transparency.rs (line 381)
337fn change_setting(
338    new_app_setting: &AppSetting,
339    app_state: &mut AppState,
340    camera: Single<(Entity, Has<OrderIndependentTransparencySettings>), With<Camera3d>>,
341    radio_group_q: Query<(&Children, &RadioGroupSetting), With<RadioGroup>>,
342    setting_q: Query<(Entity, &RadioButtonOptionValue<AppSetting>), With<RadioButton>>,
343    commands: &mut Commands,
344) {
345    let radio_group_setting = match *new_app_setting {
346        AppSetting::EnableOIT(value) => {
347            app_state.use_oit = value;
348            if app_state.use_oit {
349                commands.entity(camera.0).insert(app_state.oit_settings);
350            } else {
351                commands
352                    .entity(camera.0)
353                    .remove::<OrderIndependentTransparencySettings>();
354            }
355            RadioGroupSetting::EnableOIT
356        }
357        AppSetting::UseDepthPrepass(value) => {
358            app_state.use_depth_prepass = value;
359
360            if app_state.use_depth_prepass {
361                commands.entity(camera.0).insert(DepthPrepass);
362            } else {
363                commands.entity(camera.0).remove::<DepthPrepass>();
364            }
365            RadioGroupSetting::UseDepthPrepass
366        }
367        AppSetting::ChangeScene(id) => {
368            if id != app_state.current_scene_id {
369                app_state.current_scene_id = id;
370            }
371            RadioGroupSetting::ChangeScene
372            // The actual scene change is handled by scene_change_watcher()
373        }
374    };
375
376    // Update the radio group
377    for (children, group_setting) in radio_group_q.iter() {
378        if *group_setting != radio_group_setting {
379            continue;
380        }
381        for (entity, setting) in setting_q.iter_many(children).matched() {
382            if setting.0 == *new_app_setting {
383                commands.entity(entity).insert(Checked);
384            } else {
385                commands.entity(entity).remove::<Checked>();
386            }
387        }
388    }
389}
Source

pub fn iter_many_mut<EntityList>( &mut self, entities: EntityList, ) -> QueryManyIter<'_, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: IntoIterator, <EntityList as IntoIterator>::Item: EntityEquivalent,

Returns an iterator over the query items generated from an Entity list.

Items are returned in the order of the list of entities, and may not be unique if the input doesn’t guarantee uniqueness. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Examples
#[derive(Component)]
struct Counter {
    value: i32
}

#[derive(Component)]
struct Friends {
    list: Vec<Entity>,
}

fn system(
    friends_query: Query<&Friends>,
    mut counter_query: Query<&mut Counter>,
) {
    for friends in &friends_query {
        let mut iter = counter_query.iter_many_mut(&friends.list).matched();
        while let Some(mut counter) = iter.fetch_next() {
            println!("Friend's counter: {}", counter.value);
            counter.value += 1;
        }
    }
}
§See also
Source

pub fn iter_many_inner<EntityList>( self, entities: EntityList, ) -> QueryManyIter<'w, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: IntoIterator, <EntityList as IntoIterator>::Item: EntityEquivalent,

Returns an iterator over the query items generated from an Entity list. This consumes the Query to return results with the actual “inner” world lifetime.

Items are returned in the order of the list of entities, and may not be unique if the input doesn’t guarantee uniqueness. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§See also
Source

pub fn iter_many_unique<EntityList>( &self, entities: EntityList, ) -> QueryManyUniqueIter<'_, 's, <D as QueryData>::ReadOnly, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: EntitySet,

Returns an Iterator over the unique read-only query items generated from an EntitySet.

Items are returned in the order of the list of entities. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Example
// `Friends` ensures that it only lists unique entities.
#[derive(Component)]
struct Friends {
    unique_list: Vec<Entity>,
}

impl<'a> IntoIterator for &'a Friends {

    type Item = &'a Entity;
    type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;

    fn into_iter(self) -> Self::IntoIter {
        // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
       unsafe { UniqueEntityIter::from_iter_unchecked(self.unique_list.iter()) }
    }
}

fn system(
    friends_query: Query<&Friends>,
    counter_query: Query<&Counter>,
) {
    for friends in &friends_query {
        for counter in counter_query.iter_many_unique(friends).matched() {
            println!("Friend's counter: {:?}", counter.value);
        }
    }
}
§See also
Source

pub fn iter_many_unique_mut<EntityList>( &mut self, entities: EntityList, ) -> QueryManyUniqueIter<'_, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: EntitySet, D: IterQueryData,

Returns an iterator over the unique query items generated from an EntitySet.

Items are returned in the order of the list of entities. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Examples
#[derive(Component)]
struct Counter {
    value: i32
}

// `Friends` ensures that it only lists unique entities.
#[derive(Component)]
struct Friends {
    unique_list: Vec<Entity>,
}

impl<'a> IntoIterator for &'a Friends {
    type Item = &'a Entity;
    type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;

    fn into_iter(self) -> Self::IntoIter {
        // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
        unsafe { UniqueEntityIter::from_iter_unchecked(self.unique_list.iter()) }
    }
}

fn system(
    friends_query: Query<&Friends>,
    mut counter_query: Query<&mut Counter>,
) {
    for friends in &friends_query {
        for mut counter in counter_query.iter_many_unique_mut(friends).matched() {
            println!("Friend's counter: {:?}", counter.value);
            counter.value += 1;
        }
    }
}
§See also
Source

pub fn iter_many_unique_inner<EntityList>( self, entities: EntityList, ) -> QueryManyUniqueIter<'w, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: EntitySet, D: IterQueryData,

Returns an iterator over the unique query items generated from an EntitySet. This consumes the Query to return results with the actual “inner” world lifetime.

Items are returned in the order of the list of entities. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Examples
#[derive(Component)]
struct Counter {
    value: i32
}

// `Friends` ensures that it only lists unique entities.
#[derive(Component)]
struct Friends {
    unique_list: Vec<Entity>,
}

impl<'a> IntoIterator for &'a Friends {
    type Item = &'a Entity;
    type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;

    fn into_iter(self) -> Self::IntoIter {
        // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
        unsafe { UniqueEntityIter::from_iter_unchecked(self.unique_list.iter()) }
    }
}

fn system(
    friends_query: Query<&Friends>,
    mut counter_query: Query<&mut Counter>,
) {
    let friends = friends_query.single().unwrap();
    for mut counter in counter_query.iter_many_unique_inner(friends).matched() {
        println!("Friend's counter: {:?}", counter.value);
        counter.value += 1;
    }
}
§See also
Source

pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, D, F> ⓘ
where D: IterQueryData,

Returns an Iterator over the query items.

This iterator is always guaranteed to return results from each matching entity once and only once. Iteration order is not guaranteed.

If the QueryData does not implement IterQueryData, then it is not sound to yield multiple items concurrently and the resulting QueryIter will not implement Iterator. To iterate over the items in that case, use the QueryIter::fetch_next() method, which ensures only one item is alive at a time.

§Safety

This function makes it possible to violate Rust’s aliasing guarantees. You must make sure this call does not result in multiple mutable references to the same component.

§See also
Source

pub unsafe fn iter_combinations_unsafe<const K: usize>( &self, ) -> QueryCombinationIter<'_, 's, D, F, K> ⓘ
where D: IterQueryData,

Iterates over all possible combinations of K query items without repetition.

This iterator is always guaranteed to return results from each unique pair of matching entities. Iteration order is not guaranteed.

§Safety

This allows aliased mutability. You must make sure this call does not result in multiple mutable references to the same component.

§See also
Source

pub unsafe fn iter_many_unsafe<EntityList>( &self, entities: EntityList, ) -> QueryManyIter<'_, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: IntoIterator, <EntityList as IntoIterator>::Item: EntityEquivalent,

Returns an Iterator over the query items generated from an Entity list.

Items are returned in the order of the list of entities, and may not be unique if the input doesnn’t guarantee uniqueness. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Safety

This allows aliased mutability and does not check for entity uniqueness. You must make sure this call does not result in multiple mutable references to the same component. Particular care must be taken when collecting the data (rather than iterating over it one item at a time) such as via Iterator::collect.

§See also
Source

pub unsafe fn iter_many_unique_unsafe<EntityList>( &self, entities: EntityList, ) -> QueryManyUniqueIter<'_, 's, D, F, <EntityList as IntoIterator>::IntoIter> ⓘ
where EntityList: EntitySet, D: IterQueryData,

Returns an Iterator over the unique query items generated from an Entity list.

Items are returned in the order of the list of entities. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

§Safety

This allows aliased mutability. You must make sure this call does not result in multiple mutable references to the same component.

§See also
Source

pub fn par_iter(&self) -> QueryParIter<'_, 's, <D as QueryData>::ReadOnly, F>

Returns a parallel iterator over the query results for the given World.

This parallel iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryIter.

This can only be called for read-only queries, see par_iter_mut for write-queries.

Note that you must use the for_each method to iterate over the results, see par_iter_mut for an example.

Examples found in repository?
examples/shader_advanced/manual_material.rs (line 297)
274fn check_entities_needing_specialization(
275    needs_specialization: Query<
276        Entity,
277        (
278            Or<(
279                Changed<Mesh3d>,
280                AssetChanged<Mesh3d>,
281                Changed<ImageMaterial3d>,
282                AssetChanged<ImageMaterial3d>,
283            )>,
284            With<ImageMaterial3d>,
285        ),
286    >,
287    mut par_local: Local<Parallel<Vec<Entity>>>,
288    mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<ImageMaterial>>,
289    mut removed_mesh_3d_components: RemovedComponents<Mesh3d>,
290    mut removed_mesh_material_3d_components: RemovedComponents<ImageMaterial3d>,
291) {
292    entities_needing_specialization.changed.clear();
293    entities_needing_specialization.removed.clear();
294
295    // Gather all entities that need their specializations regenerated.
296    needs_specialization
297        .par_iter()
298        .for_each(|entity| par_local.borrow_local_mut().push(entity));
299    par_local.drain_into(&mut entities_needing_specialization.changed);
300
301    // All entities that removed their `Mesh3d` or `ImageMaterial3d` components
302    // need to have their specializations removed as well.
303    for entity in removed_mesh_3d_components
304        .read()
305        .chain(removed_mesh_material_3d_components.read())
306    {
307        entities_needing_specialization.removed.push(entity);
308    }
309}
Source

pub fn par_iter_mut(&mut self) -> QueryParIter<'_, 's, D, F>
where D: IterQueryData,

Returns a parallel iterator over the query results for the given World.

This parallel iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryIter.

This can only be called for mutable queries, see par_iter for read-only-queries.

§Example

Here, the gravity_system updates the Velocity component of every entity that contains it:

fn gravity_system(mut query: Query<&mut Velocity>) {
    const DELTA: f32 = 1.0 / 60.0;
    query.par_iter_mut().for_each(|mut velocity| {
        velocity.y -= 9.8 * DELTA;
    });
}
Examples found in repository?
examples/stress_tests/bevymark_3d.rs (line 453)
452fn collision_system(mut cube_query: Query<(&mut Cube, &Transform)>) {
453    cube_query.par_iter_mut().for_each(|(mut cube, transform)| {
454        handle_collision(&transform.translation, &mut cube.velocity);
455    });
456}
More examples
Hide additional examples
examples/stress_tests/many_cubes.rs (line 643)
639fn rotate_cubes(
640    mut query: Query<&mut Transform, (With<Mesh3d>, Without<NotShadowCaster>)>,
641    time: Res<Time>,
642) {
643    query.par_iter_mut().for_each(|mut transform| {
644        transform.rotate_y(10.0 * time.delta_secs());
645    });
646}
examples/ecs/parallel_query.rs (line 38)
28fn move_system(mut sprites: Query<(&mut Transform, &Velocity)>) {
29    // Compute the new location of each sprite in parallel on the
30    // ComputeTaskPool
31    //
32    // This example is only for demonstrative purposes. Using a
33    // ParallelIterator for an inexpensive operation like addition on only 128
34    // elements will not typically be faster than just using a normal Iterator.
35    // See the ParallelIterator documentation for more information on when
36    // to use or not use ParallelIterator over a normal Iterator.
37    sprites
38        .par_iter_mut()
39        .for_each(|(mut transform, velocity)| {
40            transform.translation += velocity.extend(0.0);
41        });
42}
43
44// Bounce sprites outside the window
45fn bounce_system(window: Query<&Window>, mut sprites: Query<(&Transform, &mut Velocity)>) {
46    let Ok(window) = window.single() else {
47        return;
48    };
49    let width = window.width();
50    let height = window.height();
51    let left = width / -2.0;
52    let right = width / 2.0;
53    let bottom = height / -2.0;
54    let top = height / 2.0;
55    // The default batch size can also be overridden.
56    // In this case a batch size of 32 is chosen to limit the overhead of
57    // ParallelIterator, since negating a vector is very inexpensive.
58    sprites
59        .par_iter_mut()
60        .batching_strategy(BatchingStrategy::fixed(32))
61        .for_each(|(transform, mut v)| {
62            if !(left < transform.translation.x
63                && transform.translation.x < right
64                && bottom < transform.translation.y
65                && transform.translation.y < top)
66            {
67                // For simplicity, just reverse the velocity; don't use realistic bounces
68                v.0 = -v.0;
69            }
70        });
71}
Source

pub fn par_iter_inner(self) -> QueryParIter<'w, 's, D, F>
where D: IterQueryData,

Returns a parallel iterator over the query results for the given World. This consumes the Query to return results with the actual “inner” world lifetime.

This parallel iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryIter.

§Example

Here, the gravity_system updates the Velocity component of every entity that contains it:

fn gravity_system(query: Query<&mut Velocity>) {
    const DELTA: f32 = 1.0 / 60.0;
    query.par_iter_inner().for_each(|mut velocity| {
        velocity.y -= 9.8 * DELTA;
    });
}
Source

pub fn par_iter_many<EntityList>( &self, entities: EntityList, ) -> QueryParManyIter<'_, 's, <D as QueryData>::ReadOnly, F, <EntityList as IntoIterator>::Item>
where EntityList: IntoIterator, <EntityList as IntoIterator>::Item: EntityEquivalent,

Returns a parallel iterator over the read-only query items generated from an Entity list.

In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryManyIter.

This can only be called for read-only queries. To avoid potential aliasing, there is no par_iter_many_mut equivalent. See par_iter_many_unique_mut for an alternative using EntitySet.

Note that you must use the for_each method to iterate over the results, see par_iter_mut for an example.

Source

pub fn par_iter_many_unique<EntityList>( &self, entities: EntityList, ) -> QueryParManyUniqueIter<'_, 's, <D as QueryData>::ReadOnly, F, <EntityList as IntoIterator>::Item>
where EntityList: EntitySet, <EntityList as IntoIterator>::Item: Sync,

Returns a parallel iterator over the unique read-only query items generated from an EntitySet.

Iteration order and thread assignment is not guaranteed. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryManyUniqueIter.

This can only be called for read-only queries, see par_iter_many_unique_mut for write-queries.

Note that you must use the for_each method to iterate over the results, see par_iter_mut for an example.

Source

pub fn par_iter_many_unique_mut<EntityList>( &mut self, entities: EntityList, ) -> QueryParManyUniqueIter<'_, 's, D, F, <EntityList as IntoIterator>::Item>
where EntityList: EntitySet, <EntityList as IntoIterator>::Item: Sync, D: IterQueryData,

Returns a parallel iterator over the unique query items generated from an EntitySet.

Iteration order and thread assignment is not guaranteed. In case of a nonexisting entity or mismatched component, a QueryEntityError is generated instead.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryManyUniqueIter.

This can only be called for mutable queries, see par_iter_many_unique for read-only-queries.

Note that you must use the for_each method to iterate over the results, see par_iter_mut for an example.

Source

pub fn contiguous_iter( &self, ) -> Result<QueryContiguousIter<'_, 's, <D as QueryData>::ReadOnly, F>, QueryNotDenseError>

Returns a contiguous iterator over the query results for the given World or Err with QueryNotDenseError if the query is not dense hence not contiguously iterable.

Contiguous iteration enables getting slices of contiguously lying components (which lie in the same table), which for example may be used for simd-operations, which may accelerate an algorithm.

§Example

The following system despawns all entities which health is negative.


fn despawn_all_dead_entities(mut commands: Commands, query: Query<(Entity, &Health)>) {
    for (entities, health) in query.contiguous_iter().unwrap() {
        // For each entity there is one component, hence it always holds true
        assert!(entities.len() == health.len());
        for (entity, health) in entities.iter().zip(health.iter()) {
            if health.0 < 0.0 {
                commands.entity(*entity).despawn();
            }
        }
    }
}

A mutable version: Self::contiguous_iter_mut

Examples found in repository?
examples/ecs/custom_query_param.rs (line 217)
215fn print_components_contiguous_iter(query: Query<CustomContiguousQuery<ComponentC, ComponentD>>) {
216    println!("Print components (contiguous_iter):");
217    for e in query.contiguous_iter().unwrap() {
218        let e: CustomContiguousQueryContiguousItem<'_, '_, _, _> = e;
219        println!("Entity: {:?}", e.entity);
220        println!("A: {:?}", e.a);
221        println!("B: {:?}", e.b);
222        println!(
223            "Generic: {:?} {:?}",
224            e.generic.generic.0, e.generic.generic.1
225        );
226    }
227}
Source

pub fn contiguous_iter_mut( &mut self, ) -> Result<QueryContiguousIter<'_, 's, D, F>, QueryNotDenseError>

Returns a mutable contiguous iterator over the query results for the given World or Err with QueryNotDenseError if the query is not dense hence not contiguously iterable.

Contiguous iteration enables getting slices of contiguously lying components (which lie in the same table), which for example may be used for simd-operations, which may accelerate an algorithm.

§Example

The following system applies a “health decay” effect on all entities, which reduces their health by some fraction.


fn apply_health_decay(mut query: Query<(&mut Health, &HealthDecay)>) {
    for (mut health, decay) in query.contiguous_iter_mut().unwrap() {
        // all data slices returned by component queries are the same size
        assert!(health.len() == decay.len());
        // we could have used health.bypass_change_detection() to do less work.
        for (health, decay) in health.iter_mut().zip(decay) {
            health.0 *= decay.0;
        }
    }
}

An immutable version: Self::contiguous_iter

Examples found in repository?
examples/ecs/contiguous_query.rs (line 28)
26fn apply_health_decay(mut query: Query<(&mut Health, &HealthDecay)>) {
27    // contiguous_iter_mut() would return None if query couldn't be iterated contiguously
28    for (mut health, decay) in query.contiguous_iter_mut().unwrap() {
29        // all data slices returned by component queries are the same size
30        assert!(health.len() == decay.len());
31        // we could also bypass change detection via bypass_change_detection() because we do not
32        // use it anyways.
33        for (health, decay) in health.iter_mut().zip(decay) {
34            health.0 *= decay.0;
35        }
36    }
37}
Source

pub fn contiguous_iter_inner( self, ) -> Result<QueryContiguousIter<'w, 's, D, F>, QueryNotDenseError>

Returns a contiguous iterator over the query results for the given World or Err with QueryNotDenseError if the query is not dense hence not contiguously iterable. This consumes the Query to return results with the actual “inner” world lifetime.

Source

pub fn contiguous_par_iter( &self, ) -> Result<QueryContiguousParIter<'_, 's, <D as QueryData>::ReadOnly, F>, QueryNotDenseError>

Returns a parallel iterator over contiguous query results for the given World.

Contiguous iteration enables getting slices of contiguously laid out components that reside in the same table. These slices may for example be used for SIMD operations.

This parallel iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the query isn’t contiguously iterable because it isn’t dense, this method returns a QueryNotDenseError.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryContiguousIter.

This can only be called for read-only queries. For queries that may write to the components they query, see Self::par_iter_mut.

Note that you must use the for_each method to iterate over the results. See Self::contiguous_par_iter_mut for an example.

Source

pub fn contiguous_par_iter_mut( &mut self, ) -> Result<QueryContiguousParIter<'_, 's, D, F>, QueryNotDenseError>

Returns a parallel iterator over contiguous query results for the given World.

Contiguous iteration enables getting slices of contiguously laid out components that reside in the same table. These slices may for example be used for SIMD operations.

This parallel contiguous iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryContiguousIter.

This can only be called for mutable queries. See par_iter for read-only queries.

§Example

Here, the gravity_system updates the Velocity component of every entity that contains it:

fn gravity_system(mut query: Query<&mut Velocity>) {
    const DELTA: f32 = 1.0 / 60.0;
    query.contiguous_par_iter_mut().unwrap().for_each(|mut velocities| {
        for mut velocity in velocities {
            velocity.y -= 9.8 * DELTA;
        }
    });
}
Source

pub fn contiguous_par_iter_inner( self, ) -> Result<QueryContiguousParIter<'w, 's, D, F>, QueryNotDenseError>

Returns a parallel iterator over contiguous query results for the given World. This consumes the Query to return results with the actual “inner” world lifetime.

Contiguous iteration enables getting slices of contiguously laid out components that reside in the same table. These slices may for example be used for SIMD operations.

This parallel iterator is always guaranteed to return results from each matching entity once and only once. Iteration order and thread assignment is not guaranteed.

If the multithreaded feature is disabled, iterating with this operates identically to Iterator::for_each on QueryContiguousIter.

Source

pub fn get( &self, entity: Entity, ) -> Result<<<D as QueryData>::ReadOnly as QueryData>::Item<'_, 's>, QueryEntityError>

Returns the read-only query item for the given Entity.

In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

This is always guaranteed to run in O(1) time.

§Example

Here, get is used to retrieve the exact query item of the entity specified by the SelectedCharacter resource.

fn print_selected_character_name_system(
       query: Query<&Character>,
       selection: Res<SelectedCharacter>
)
{
    if let Ok(selected_character) = query.get(selection.entity) {
        println!("{}", selected_character.name);
    }
}
§See also
  • get_mut to get a mutable query item.
Examples found in repository?
examples/ecs/observer_propagation.rs (line 80)
79fn attack_hits(attack: On<Attack>, name: Query<&Name>) {
80    if let Ok(name) = name.get(attack.entity) {
81        info!("Attack hit {}", name);
82    }
83}
84
85/// A callback placed on [`Armor`], checking if it absorbed all the [`Attack`] damage.
86fn block_attack(mut attack: On<Attack>, armor: Query<(&Armor, &Name)>) {
87    let (armor, name) = armor.get(attack.entity).unwrap();
88    let damage = attack.damage.saturating_sub(**armor);
89    if damage > 0 {
90        info!("🩸 {} damage passed through {}", damage, name);
91        // The attack isn't stopped by the armor. We reduce the damage of the attack, and allow
92        // it to continue on to the goblin.
93        attack.damage = damage;
94    } else {
95        info!("🛡️  {} damage blocked by {}", attack.damage, name);
96        // Armor stopped the attack, the event stops here.
97        attack.propagate(false);
98        info!("(propagation halted early)\n");
99    }
100}
More examples
Hide additional examples
examples/3d/clustered_decal_maps.rs (line 402)
397fn handle_emission_type_change(
398    event: On<ValueChange<Entity>>,
399    new_value_q: Query<&RadioButtonOptionValue<AppSetting>>,
400    mut app_status: ResMut<AppStatus>,
401) {
402    let Ok(RadioButtonOptionValue(setting)) = new_value_q.get(event.value) else {
403        return;
404    };
405
406    let AppSetting::EmissiveDecals(on) = *setting;
407    app_status.emissive_decals = on;
408}
examples/2d/dynamic_mip_generation.rs (line 474)
469fn handle_enable_mip_generation_change(
470    event: On<ValueChange<Entity>>,
471    new_value_query: Query<&RadioButtonOptionValue<EnableMipGeneration>>,
472    mut app_status: ResMut<AppStatus>,
473) {
474    let Ok(RadioButtonOptionValue(enable_mip)) = new_value_query.get(event.value) else {
475        return;
476    };
477    app_status.enable_mip_generation = *enable_mip;
478
479    // Enabling mip generation does not trigger a request to regenerate the image.
480}
481
482/// Handles a request from the user to change the image size via the UI.
483fn handle_image_size_setting_change(
484    event: On<ValueChange<Entity>>,
485    new_value_query: Query<&RadioButtonOptionValue<ImageSizeSetting>>,
486    mut app_status: ResMut<AppStatus>,
487    mut regenerate_image_message_writer: MessageWriter<RegenerateImage>,
488) {
489    let Ok(RadioButtonOptionValue(size_setting)) = new_value_query.get(event.value) else {
490        return;
491    };
492
493    match *size_setting {
494        ImageSizeSetting::ImageWidth(image_size) => app_status.image_width = image_size,
495        ImageSizeSetting::ImageHeight(image_size) => app_status.image_height = image_size,
496    }
497
498    // Schedule the image to be regenerated.
499    regenerate_image_message_writer.write(RegenerateImage);
500}
examples/3d/light_probe_blending.rs (line 442)
436fn handle_gizmos_enabled_change(
437    event: On<ValueChange<Entity>>,
438    new_value_query: Query<&RadioButtonOptionValue<GizmosEnabled>>,
439    mut app_status: ResMut<AppStatus>,
440    mut help_text_query: Query<&mut Text, With<HelpText>>,
441) {
442    let Ok(RadioButtonOptionValue(enabled)) = new_value_query.get(event.value) else {
443        return;
444    };
445    app_status.gizmos_enabled = *enabled;
446
447    set_help_text(&app_status, &mut help_text_query);
448}
449
450/// Handles requests from the user to toggle which object is showing.
451/// The `radio_self_update` observer handles setting the `Checked` state on the radio buttons.
452fn handle_object_to_show_change(
453    event: On<ValueChange<Entity>>,
454    new_value_query: Query<&RadioButtonOptionValue<ObjectToShow>>,
455    mut app_status: ResMut<AppStatus>,
456    mut spheres_query: Query<&mut Visibility, (With<ReflectiveSphere>, Without<ReflectivePrism>)>,
457    mut prisms_query: Query<&mut Visibility, (With<ReflectivePrism>, Without<ReflectiveSphere>)>,
458) {
459    let Ok(RadioButtonOptionValue(object_to_show)) = new_value_query.get(event.value) else {
460        return;
461    };
462    app_status.object_to_show = *object_to_show;
463
464    for mut sphere_visibility in &mut spheres_query {
465        *sphere_visibility = match app_status.object_to_show {
466            ObjectToShow::Sphere => Visibility::Inherited,
467            ObjectToShow::Prism => Visibility::Hidden,
468        }
469    }
470    for mut prism_visibility in &mut prisms_query {
471        *prism_visibility = match app_status.object_to_show {
472            ObjectToShow::Sphere => Visibility::Hidden,
473            ObjectToShow::Prism => Visibility::Inherited,
474        }
475    }
476}
477
478/// Handles requests from the user to switch the camera mode when the user clicks on one of the
479/// corresponding radio buttons.
480fn handle_camera_mode_change(
481    event: On<ValueChange<Entity>>,
482    new_value_query: Query<&RadioButtonOptionValue<CameraMode>>,
483    mut commands: Commands,
484    cameras_query: Query<(Entity, &Transform), With<Camera3d>>,
485    sphere_query: Query<&Transform, (With<ReflectiveSphere>, Without<Camera3d>)>,
486    mut help_text_query: Query<&mut Text, With<HelpText>>,
487    mut windows_query: Query<&mut CursorOptions>,
488    mut app_status: ResMut<AppStatus>,
489) {
490    let Some(sphere_transform) = sphere_query.iter().next() else {
491        return;
492    };
493
494    let Ok(RadioButtonOptionValue(camera_mode)) = new_value_query.get(event.value) else {
495        return;
496    };
497
498    app_status.camera_mode = *camera_mode;
499
500    match app_status.camera_mode {
501        CameraMode::Orbit => {
502            for (camera_entity, camera_transform) in &cameras_query {
503                // Convert from Cartesian coordinates back to spherical
504                // coordinates.
505                let relative_camera_position =
506                    camera_transform.translation - sphere_transform.translation;
507                let radius = relative_camera_position.length();
508                let inclination = atan2(
509                    relative_camera_position.xz().length() / radius,
510                    relative_camera_position.y / radius,
511                );
512                let azimuth = atan2(
513                    relative_camera_position.z * relative_camera_position.xz().length_recip(),
514                    relative_camera_position.x * relative_camera_position.xz().length_recip(),
515                );
516
517                commands
518                    .entity(camera_entity)
519                    .remove::<FreeCamera>()
520                    .insert(OrbitCamera {
521                        radius,
522                        inclination,
523                        azimuth,
524                    });
525            }
526        }
527
528        CameraMode::Free => {
529            for (camera_entity, _) in &cameras_query {
530                commands
531                    .entity(camera_entity)
532                    .remove::<OrbitCamera>()
533                    .insert(FreeCamera::default());
534            }
535        }
536    }
537
538    set_help_text(&app_status, &mut help_text_query);
539
540    // Reset the cursor grab mode, because the free camera controller may
541    // have enabled it, and we don't want the cursor to disappear.
542    for mut cursor_options in &mut windows_query {
543        cursor_options.grab_mode = CursorGrabMode::None;
544        cursor_options.visible = true;
545    }
546}
examples/3d/ssr.rs (line 637)
630fn handle_value_change_ssr_on(
631    event: On<ValueChange<Entity>>,
632    new_value_query: Query<&radio::RadioButtonOptionValue<SsrOn>>,
633    commands: Commands,
634    mut app_settings: ResMut<AppSettings>,
635    cameras: Query<Entity, With<Camera>>,
636) {
637    let Ok(radio::RadioButtonOptionValue(ssr_on)) = new_value_query.get(event.value) else {
638        return;
639    };
640    app_settings.ssr_on = *ssr_on;
641
642    update_views(commands, app_settings, cameras);
643}
644
645/// Update the camera views, particularly after `SsrOn` or any of the number inputs change
646fn update_views(
647    mut commands: Commands,
648    app_settings: ResMut<AppSettings>,
649    mut cameras: Query<Entity, With<Camera>>,
650) {
651    for camera in cameras.iter_mut() {
652        if app_settings.ssr_on.0 {
653            commands.entity(camera).insert(ScreenSpaceReflections {
654                min_perceptual_roughness: app_settings.min_perceptual_roughness.clone(),
655                max_perceptual_roughness: app_settings.max_perceptual_roughness.clone(),
656                edge_fadeout: app_settings.edge_fadeout.clone(),
657                ..default()
658            });
659        } else {
660            commands.entity(camera).remove::<ScreenSpaceReflections>();
661        }
662    }
663}
664
665/// Handles changes to the `DisplayedModel` radio group.
666fn handle_value_change_displayed_model(
667    event: On<ValueChange<Entity>>,
668    new_value_query: Query<&radio::RadioButtonOptionValue<DisplayedModel>>,
669    mut app_settings: ResMut<AppSettings>,
670    model_queries: ModelQueries,
671    mut visibilities: Query<&mut Visibility>,
672) {
673    let Ok(radio::RadioButtonOptionValue(displayed_model)) = new_value_query.get(event.value)
674    else {
675        return;
676    };
677    app_settings.displayed_model = *displayed_model;
678
679    for entity in model_queries.cube_models.iter() {
680        if let Ok(mut visibility) = visibilities.get_mut(entity) {
681            *visibility = if app_settings.displayed_model == DisplayedModel::Cube {
682                Visibility::Visible
683            } else {
684                Visibility::Hidden
685            };
686        }
687    }
688    for entity in model_queries.flight_helmet_models.iter() {
689        if let Ok(mut visibility) = visibilities.get_mut(entity) {
690            *visibility = if app_settings.displayed_model == DisplayedModel::FlightHelmet {
691                Visibility::Visible
692            } else {
693                Visibility::Hidden
694            };
695        }
696    }
697    for entity in model_queries.capsule_models.iter() {
698        if let Ok(mut visibility) = visibilities.get_mut(entity) {
699            *visibility = if app_settings.displayed_model == DisplayedModel::Capsules {
700                Visibility::Visible
701            } else {
702                Visibility::Hidden
703            };
704        }
705    }
706}
707
708/// Handles changes to the `DisplayedBase` radio group.
709fn handle_value_change_displayed_base(
710    event: On<ValueChange<Entity>>,
711    new_value_query: Query<&radio::RadioButtonOptionValue<DisplayedBase>>,
712    mut app_settings: ResMut<AppSettings>,
713    model_queries: ModelQueries,
714    mut visibilities: Query<&mut Visibility>,
715) {
716    let Ok(radio::RadioButtonOptionValue(displayed_base)) = new_value_query.get(event.value) else {
717        return;
718    };
719    app_settings.displayed_base = *displayed_base;
720
721    for entity in model_queries.metallic_base_models.iter() {
722        if let Ok(mut visibility) = visibilities.get_mut(entity) {
723            *visibility = if app_settings.displayed_base == DisplayedBase::Metallic {
724                Visibility::Visible
725            } else {
726                Visibility::Hidden
727            };
728        }
729    }
730    for entity in model_queries.non_metallic_base_models.iter() {
731        if let Ok(mut visibility) = visibilities.get_mut(entity) {
732            *visibility = if app_settings.displayed_base == DisplayedBase::RedPlane {
733                Visibility::Visible
734            } else {
735                Visibility::Hidden
736            };
737        }
738    }
739    for entity in model_queries.water_models.iter() {
740        if let Ok(mut visibility) = visibilities.get_mut(entity) {
741            *visibility = if app_settings.displayed_base == DisplayedBase::Water {
742                Visibility::Visible
743            } else {
744                Visibility::Hidden
745            };
746        }
747    }
748}
749
750/// Observer that handles changes to number inputs and updates state and the app accordingly.
751fn handle_value_change_number_input(
752    value_change: On<ValueChange<f32>>,
753    mut commands: Commands,
754    number_input_q: Query<&AppNumberInput, With<FeathersNumberInput>>,
755    mut app_settings: ResMut<AppSettings>,
756    cameras: Query<Entity, With<Camera>>,
757) {
758    if let Ok(app_number_input) = number_input_q.get(value_change.source) {
759        match app_number_input {
760            AppNumberInput::MinRoughnessStart => {
761                app_settings.min_perceptual_roughness.start = value_change.value;
762            }
763            AppNumberInput::MinRoughnessEnd => {
764                app_settings.min_perceptual_roughness.end = value_change.value;
765            }
766            AppNumberInput::MaxRoughnessStart => {
767                app_settings.max_perceptual_roughness.start = value_change.value;
768            }
769            AppNumberInput::MaxRoughnessEnd => {
770                app_settings.max_perceptual_roughness.end = value_change.value;
771            }
772            AppNumberInput::EdgeFadeoutStart => {
773                app_settings.edge_fadeout.start = value_change.value;
774            }
775            AppNumberInput::EdgeFadeoutEnd => {
776                app_settings.edge_fadeout.end = value_change.value;
777            }
778        }
779
780        commands
781            .entity(value_change.source)
782            .insert(NumberInputValue::F32(value_change.value));
783
784        update_views(commands, app_settings, cameras);
785    }
786}
examples/3d/mixed_lighting.rs (line 377)
371fn handle_lighting_mode_change(
372    event: On<ValueChange<Entity>>,
373    new_value_q: Query<&RadioButtonOptionValue<LightingMode>>,
374    mut lighting_mode_changed_writer: MessageWriter<LightingModeChanged>,
375    mut app_status: ResMut<AppStatus>,
376) {
377    let Ok(RadioButtonOptionValue(new_lighting_mode)) = new_value_q.get(event.value) else {
378        return;
379    };
380
381    app_status.lighting_mode = *new_lighting_mode;
382    lighting_mode_changed_writer.write(LightingModeChanged);
383}
Source

pub fn get_many<const N: usize>( &self, entities: [Entity; N], ) -> Result<[<<D as QueryData>::ReadOnly as QueryData>::Item<'_, 's>; N], QueryEntityError>

Returns the read-only query items for the given array of Entity.

The returned query items are in the same order as the input. In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead. The elements of the array do not need to be unique, unlike get_many_mut.

§Examples
use bevy_ecs::prelude::*;
use bevy_ecs::query::QueryEntityError;

#[derive(Component, PartialEq, Debug)]
struct A(usize);

let mut world = World::new();
let entity_vec: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
let entities: [Entity; 3] = entity_vec.try_into().unwrap();

world.spawn(A(73));

let mut query_state = world.query::<&A>();
let query = query_state.query(&world);

let component_values = query.get_many(entities).unwrap();

assert_eq!(component_values, [&A(0), &A(1), &A(2)]);

let wrong_entity = Entity::from_raw_u32(365).unwrap();

assert_eq!(
    match query.get_many([wrong_entity]).unwrap_err() {
        QueryEntityError::NotSpawned(error) => error.entity(),
        _ => panic!(),
    },
    wrong_entity
);
§See also
Source

pub fn get_many_unique<const N: usize>( &self, entities: UniqueEntityEquivalentArray<Entity, N>, ) -> Result<[<<D as QueryData>::ReadOnly as QueryData>::Item<'_, 's>; N], QueryEntityError>

Returns the read-only query items for the given UniqueEntityArray.

The returned query items are in the same order as the input. In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

§Examples
use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};

#[derive(Component, PartialEq, Debug)]
struct A(usize);

let mut world = World::new();
let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();

world.spawn(A(73));

let mut query_state = world.query::<&A>();
let query = query_state.query(&world);

let component_values = query.get_many_unique(entity_set).unwrap();

assert_eq!(component_values, [&A(0), &A(1), &A(2)]);

let wrong_entity = Entity::from_raw_u32(365).unwrap();

assert_eq!(
    match query.get_many_unique(UniqueEntityArray::from([wrong_entity])).unwrap_err() {
        QueryEntityError::NotSpawned(error) => error.entity(),
        _ => panic!(),
    },
    wrong_entity
);
§See also
Source

pub fn get_mut( &mut self, entity: Entity, ) -> Result<<D as QueryData>::Item<'_, 's>, QueryEntityError>

Returns the query item for the given Entity.

In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

This is always guaranteed to run in O(1) time.

§Example

Here, get_mut is used to retrieve the exact query item of the entity specified by the PoisonedCharacter resource.

fn poison_system(mut query: Query<&mut Health>, poisoned: Res<PoisonedCharacter>) {
    if let Ok(mut health) = query.get_mut(poisoned.character_id) {
        health.0 -= 1;
    }
}
§See also
  • get to get a read-only query item.
Examples found in repository?
examples/asset/asset_saving.rs (line 263)
259fn on_enter_selectable(
260    event: On<PointerEnter>,
261    mut border: Query<&mut BorderColor, (With<SelectableColor>, Without<Selected>)>,
262) {
263    let Ok(mut border) = border.get_mut(event.entity) else {
264        return;
265    };
266
267    *border = BorderColor::all(HIGHLIGHT_COLOR);
268}
269
270fn on_leave_selectable(
271    event: On<PointerLeave>,
272    mut border: Query<&mut BorderColor, (With<SelectableColor>, Without<Selected>)>,
273) {
274    let Ok(mut border) = border.get_mut(event.entity) else {
275        return;
276    };
277
278    *border = BorderColor::all(NORMAL_COLOR);
279}
280
281fn on_press_selectable(
282    event: On<PointerPress>,
283    mut borders: Query<(Entity, &mut BorderColor, &BackgroundColor), With<SelectableColor>>,
284    mut draw_color: ResMut<DrawColor>,
285    mut commands: Commands,
286) {
287    if !borders.contains(event.entity) {
288        return;
289    }
290    for (entity, mut border, _) in borders.iter_mut() {
291        commands.entity(entity).remove::<Selected>();
292        *border = BorderColor::all(NORMAL_COLOR);
293    }
294    let (_, mut border, background_color) = borders.get_mut(event.entity).unwrap();
295    *border = BorderColor::all(SELECTED_COLOR);
296    commands.entity(event.entity).insert(Selected);
297
298    draw_color.0 = background_color.0;
299}
More examples
Hide additional examples
examples/picking/sprite_picking.rs (line 157)
153fn recolor_on<E: EntityEvent + Debug + Clone + Reflect>(
154    color: Color,
155) -> impl Fn(On<E>, Query<&mut Sprite>) {
156    move |ev, mut sprites| {
157        let Ok(mut sprite) = sprites.get_mut(ev.event_target()) else {
158            return;
159        };
160        sprite.color = color;
161    }
162}
examples/ecs/removal_detection.rs (line 53)
51fn react_on_removal(remove: On<Remove<MyComponent>>, mut query: Query<&mut Sprite>) {
52    // The `Remove` event was automatically triggered for the `Entity` that had its `MyComponent` removed.
53    if let Ok(mut sprite) = query.get_mut(remove.entity) {
54        sprite.color = Color::srgb(0.5, 1., 1.);
55    }
56}
examples/showcase/mines.rs (line 448)
444fn on_button_over(
445    over: On<PointerOver>,
446    mut buttons: Query<(&mut BorderColor, &mut BackgroundColor), With<ButtonAction>>,
447) {
448    if let Ok((mut border, mut background)) = buttons.get_mut(over.event_target()) {
449        border.set_all(HOVERED_TILE_BORDER_COLOR);
450        background.0 = BACKGROUND_COLOR;
451    }
452}
453
454fn on_button_out(
455    out: On<PointerOut>,
456    mut buttons: Query<(&mut BorderColor, &mut BackgroundColor), With<ButtonAction>>,
457) {
458    if let Ok((mut border, mut background)) = buttons.get_mut(out.event_target()) {
459        border.set_all(TILE_BORDER_COLOR);
460        background.0 = BACKGROUND_COLOR;
461    }
462}
463
464fn on_tile_over(over: On<PointerOver>, mut tiles: Query<&mut BorderColor, With<TileCell>>) {
465    if let Ok(mut border) = tiles.get_mut(over.event_target()) {
466        border.set_all(HOVERED_TILE_BORDER_COLOR);
467    }
468}
469
470fn on_tile_out(out: On<PointerOut>, mut tiles: Query<&mut BorderColor, With<TileCell>>) {
471    if let Ok(mut border) = tiles.get_mut(out.event_target()) {
472        border.set_all(TILE_BORDER_COLOR);
473    }
474}
examples/ui/text/multiline_text_input.rs (line 592)
586fn on_thumb_drag_start(
587    mut on: On<PointerDragStart>,
588    mut thumb_query: Query<&mut InputScrollDragState, With<InputScrollThumb>>,
589    input: Single<&EditableText, With<MultilineInput>>,
590) {
591    on.propagate(false);
592    let Ok(mut drag) = thumb_query.get_mut(on.entity) else {
593        return;
594    };
595    drag.dragging = true;
596    drag.drag_origin = input.viewport.offset.y;
597}
598
599fn on_thumb_drag(
600    mut on: On<PointerDrag>,
601    thumb_query: Query<(&InputScrollDragState, &ChildOf), With<InputScrollThumb>>,
602    track_query: Query<&ComputedNode>,
603    mut input: Single<(&mut EditableText, &TextLayoutInfo), With<MultilineInput>>,
604) {
605    on.propagate(false);
606    let Ok((drag, ChildOf(track))) = thumb_query.get(on.entity) else {
607        return;
608    };
609    if !drag.dragging {
610        return;
611    }
612    let Ok(track_node) = track_query.get(*track) else {
613        return;
614    };
615    let track_height = track_node.size.y * track_node.inverse_scale_factor;
616    if track_height <= 0. {
617        return;
618    }
619
620    let content_height = input.1.size.y;
621    let max_offset = (content_height - input.0.viewport.size.y).max(0.);
622    let delta = on.distance.y / track_height * content_height;
623    input.0.viewport.offset.y = (drag.drag_origin + delta).clamp(0., max_offset);
624}
625
626fn on_thumb_drag_end(
627    mut on: On<PointerDragEnd>,
628    mut thumb_query: Query<&mut InputScrollDragState, With<InputScrollThumb>>,
629) {
630    on.propagate(false);
631    let Ok(mut drag) = thumb_query.get_mut(on.entity) else {
632        return;
633    };
634    drag.dragging = false;
635}
examples/ui/widgets/viewport_node.rs (line 81)
79fn on_drag_viewport(drag: On<PointerDrag>, mut node_query: Query<&mut Node>) {
80    if matches!(drag.button, PointerButton::Secondary) {
81        let mut node = node_query.get_mut(drag.entity).unwrap();
82
83        if let (Val::Px(top), Val::Px(left)) = (node.top, node.left) {
84            node.left = px(left + drag.delta.x);
85            node.top = px(top + drag.delta.y);
86        };
87    }
88}
89
90fn on_drag_cuboid(drag: On<PointerDrag>, mut transform_query: Query<&mut Transform>) {
91    if matches!(drag.button, PointerButton::Primary) {
92        let mut transform = transform_query.get_mut(drag.entity).unwrap();
93        transform.rotate_y(drag.delta.x * 0.02);
94        transform.rotate_x(drag.delta.y * 0.02);
95    }
96}
Source

pub fn get_inner( self, entity: Entity, ) -> Result<<D as QueryData>::Item<'w, 's>, QueryEntityError>

Returns the query item for the given Entity. This consumes the Query to return results with the actual “inner” world lifetime.

In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

This is always guaranteed to run in O(1) time.

§See also
  • get_mut to get the item using a mutable borrow of the Query.
Source

pub fn get_many_mut<const N: usize>( &mut self, entities: [Entity; N], ) -> Result<[<D as QueryData>::Item<'_, 's>; N], QueryEntityError>
where D: IterQueryData,

Returns the query items for the given array of Entity.

The returned query items are in the same order as the input. In case of a nonexisting entity, duplicate entities or mismatched component, a QueryEntityError is returned instead.

§Examples
use bevy_ecs::prelude::*;
use bevy_ecs::query::QueryEntityError;

#[derive(Component, PartialEq, Debug)]
struct A(usize);

let mut world = World::new();

let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
let entities: [Entity; 3] = entities.try_into().unwrap();

world.spawn(A(73));
let wrong_entity = Entity::from_raw_u32(57).unwrap();
let invalid_entity = world.spawn_empty().id();


let mut query_state = world.query::<&mut A>();
let mut query = query_state.query_mut(&mut world);

let mut mutable_component_values = query.get_many_mut(entities).unwrap();

for mut a in &mut mutable_component_values {
    a.0 += 5;
}

let component_values = query.get_many(entities).unwrap();

assert_eq!(component_values, [&A(5), &A(6), &A(7)]);

assert_eq!(
    match query
        .get_many_mut([wrong_entity])
        .unwrap_err()
    {
        QueryEntityError::NotSpawned(error) => error.entity(),
        _ => panic!(),
    },
    wrong_entity
);
assert_eq!(
    match query
        .get_many_mut([invalid_entity])
        .unwrap_err()
    {
        QueryEntityError::QueryDoesNotMatch(entity, _) => entity,
        _ => panic!(),
    },
    invalid_entity
);
assert_eq!(
    query
        .get_many_mut([entities[0], entities[0]])
        .unwrap_err(),
    QueryEntityError::AliasedMutability(entities[0])
);
§See also
  • get_many to get read-only query items without checking for duplicate entities.
Examples found in repository?
examples/ui/ui_drag_and_drop.rs (line 91)
16fn setup(mut commands: Commands) {
17    commands.spawn(Camera2d);
18    commands
19        .spawn((Node {
20            display: Display::Grid,
21            align_self: AlignSelf::Center,
22            justify_self: JustifySelf::Center,
23            ..Default::default()
24        }, Pickable::IGNORE, BackgroundColor(Color::srgb(0.4, 0.4, 0.4))))
25        .with_children(|parent| {
26            let tile_colors = [
27                Color::srgb(0.2, 0.2, 0.8),
28                Color::srgb(0.8, 0.2, 0.2)
29            ];
30            for column in 0..COLUMNS {
31                for row in 0..ROWS {
32                    let i = column + row * COLUMNS;
33                    let tile_color = tile_colors[((row % 2) + column) as usize % tile_colors.len()];
34                    let tile_border_color = tile_color.darker(0.025);
35                    parent
36                        .spawn((
37                            Node {
38                                width: px(TILE_SIZE),
39                                height: px(TILE_SIZE),
40                                border: px(4.).all(),
41                                grid_row: GridPlacement::start(row + 1),
42                                grid_column: GridPlacement::start(column + 1),
43                                align_items: AlignItems::Center,
44                                justify_content: JustifyContent::Center,
45                                ..Default::default()
46                            },
47                            BorderColor::all(tile_border_color),
48                            BackgroundColor(tile_color),
49                            Outline {
50                                width: px(2.),
51                                offset: Val::ZERO,
52                                color: Color::NONE,
53                            },
54                            Pickable {
55                                should_block_lower: false,
56                                is_hoverable: true,
57                            },
58                            GlobalZIndex::default()
59                        ))
60                        .observe(move |on_over: On<PointerOver>, mut query: Query<(&mut BackgroundColor, &mut BorderColor)>| {
61                            if let Ok((mut background_color, mut border_color)) = query.get_mut(on_over.event_target()) {
62                                background_color.0 = tile_color.lighter(0.1);
63                                border_color.set_all(tile_border_color.lighter(0.1));
64                            }
65                        })
66                        .observe(move |on_out: On<PointerOut>, mut query: Query<(&mut BackgroundColor, &mut BorderColor)>| {
67                            if let Ok((mut background_color, mut border_color)) = query.get_mut(on_out.event_target()) {
68                                background_color.0 = tile_color;
69                                border_color.set_all(tile_border_color);
70                            }
71                        })
72                        .observe(|on_drag_start: On<PointerDragStart>, mut query: Query<(&mut Outline, &mut GlobalZIndex)>| {
73                            if let Ok((mut outline, mut global_zindex, )) = query.get_mut(on_drag_start.event_target()) {
74                                outline.color = Color::WHITE;
75                                global_zindex.0 = 1;
76                            }
77                        })
78                        .observe(|on_drag: On<PointerDrag>, mut query: Query<&mut UiTransform>| {
79                            if let Ok(mut transform) = query.get_mut(on_drag.event_target()) {
80                                transform.translation = Val2::px(on_drag.distance.x, on_drag.distance.y);
81                            }
82                        })
83                        .observe(move |on_drag_end: On<PointerDragEnd>, mut query: Query<(&mut UiTransform, &mut Outline, &mut GlobalZIndex)>| {
84                            if let Ok((mut transform, mut outline, mut global_zindex)) = query.get_mut(on_drag_end.event_target()) {
85                                transform.translation = Val2::ZERO;
86                                outline.color = Color::NONE;
87                                global_zindex.0 = 0;
88                            }
89                        })
90                        .observe(|on_drag_drop: On<PointerDragDrop>, mut query: Query<&mut Node>| {
91                            if let Ok([mut a, mut b]) = query.get_many_mut([on_drag_drop.event_target(), on_drag_drop.dropped]) {
92                                core::mem::swap(&mut a.grid_row, &mut b.grid_row);
93                                core::mem::swap(&mut a.grid_column, &mut b.grid_column);
94                            }
95                        })
96                        .with_child((Text::new(format!("{i}")), Pickable::IGNORE));
97                }
98            }
99        });
100}
Source

pub fn get_many_unique_mut<const N: usize>( &mut self, entities: UniqueEntityEquivalentArray<Entity, N>, ) -> Result<[<D as QueryData>::Item<'_, 's>; N], QueryEntityError>
where D: IterQueryData,

Returns the query items for the given UniqueEntityArray.

The returned query items are in the same order as the input. In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

§Examples
use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};

#[derive(Component, PartialEq, Debug)]
struct A(usize);

let mut world = World::new();

let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();

world.spawn(A(73));
let wrong_entity = Entity::from_raw_u32(57).unwrap();
let invalid_entity = world.spawn_empty().id();


let mut query_state = world.query::<&mut A>();
let mut query = query_state.query_mut(&mut world);

let mut mutable_component_values = query.get_many_unique_mut(entity_set).unwrap();

for mut a in &mut mutable_component_values {
    a.0 += 5;
}

let component_values = query.get_many_unique(entity_set).unwrap();

assert_eq!(component_values, [&A(5), &A(6), &A(7)]);

assert_eq!(
    match query
        .get_many_unique_mut(UniqueEntityArray::from([wrong_entity]))
        .unwrap_err()
    {
        QueryEntityError::NotSpawned(error) => error.entity(),
        _ => panic!(),
    },
    wrong_entity
);
assert_eq!(
    match query
        .get_many_unique_mut(UniqueEntityArray::from([invalid_entity]))
        .unwrap_err()
    {
        QueryEntityError::QueryDoesNotMatch(entity, _) => entity,
        _ => panic!(),
    },
    invalid_entity
);
§See also
Source

pub fn get_many_mut_inner<const N: usize>( self, entities: [Entity; N], ) -> Result<[<D as QueryData>::Item<'w, 's>; N], QueryEntityError>
where D: IterQueryData,

Returns the query items for the given array of Entity. This consumes the Query to return results with the actual “inner” world lifetime.

The returned query items are in the same order as the input. In case of a nonexisting entity, duplicate entities or mismatched component, a QueryEntityError is returned instead.

§See also
  • get_many to get read-only query items without checking for duplicate entities.
  • get_many_mut to get items using a mutable reference.
  • get_many_inner to get read-only query items with the actual “inner” world lifetime.
Source

pub fn get_many_inner<const N: usize>( self, entities: [Entity; N], ) -> Result<[<D as QueryData>::Item<'w, 's>; N], QueryEntityError>

Returns the query items for the given array of Entity. This consumes the Query to return results with the actual “inner” world lifetime.

The returned query items are in the same order as the input. In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

§See also
  • get_many to get read-only query items without checking for duplicate entities.
  • get_many_mut to get items using a mutable reference.
  • get_many_mut_inner to get mutable query items with the actual “inner” world lifetime.
Source

pub fn get_many_unique_inner<const N: usize>( self, entities: UniqueEntityEquivalentArray<Entity, N>, ) -> Result<[<D as QueryData>::Item<'w, 's>; N], QueryEntityError>
where D: IterQueryData,

Returns the query items for the given UniqueEntityArray. This consumes the Query to return results with the actual “inner” world lifetime.

The returned query items are in the same order as the input. In case of a nonexisting entity, duplicate entities or mismatched component, a QueryEntityError is returned instead.

§See also
Source

pub unsafe fn get_unchecked( &self, entity: Entity, ) -> Result<<D as QueryData>::Item<'_, 's>, QueryEntityError>

Returns the query item for the given Entity.

In case of a nonexisting entity or mismatched component, a QueryEntityError is returned instead.

This is always guaranteed to run in O(1) time.

§Safety

This function makes it possible to violate Rust’s aliasing guarantees. You must make sure this call does not result in multiple mutable references to the same component.

§See also
Source

pub fn single( &self, ) -> Result<<<D as QueryData>::ReadOnly as QueryData>::Item<'_, 's>, QuerySingleError>

Returns a single read-only query item when there is exactly one entity matching the query.

If the number of query items is not exactly one, a QuerySingleError is returned instead.

§Example
fn player_scoring_system(query: Query<&PlayerScore>) {
    match query.single() {
        Ok(PlayerScore(score)) => {
            println!("Score: {}", score);
        }
        Err(QuerySingleError::NoEntities(_)) => {
            println!("Error: There is no player!");
        }
        Err(QuerySingleError::MultipleEntities(_)) => {
            println!("Error: There is more than one player!");
        }
    }
}
§See also
Examples found in repository?
examples/audio/audio_control.rs (line 62)
61fn update_speed(music_controller: Query<&AudioSink, With<MyMusic>>, time: Res<Time>) {
62    let Ok(sink) = music_controller.single() else {
63        return;
64    };
65    if sink.is_paused() {
66        return;
67    }
68
69    sink.set_speed((ops::sin(time.elapsed_secs() / 5.0) + 1.0).max(0.1));
70}
71
72fn pause(
73    keyboard_input: Res<ButtonInput<KeyCode>>,
74    music_controller: Query<&AudioSink, With<MyMusic>>,
75) {
76    let Ok(sink) = music_controller.single() else {
77        return;
78    };
79
80    if keyboard_input.just_pressed(KeyCode::Space) {
81        sink.toggle_playback();
82    }
83}
More examples
Hide additional examples
examples/camera/pan_camera_controller.rs (line 31)
23fn spawn_text(mut commands: Commands, camera: Query<&PanCamera>) {
24    commands.spawn((
25        Node {
26            position_type: PositionType::Absolute,
27            top: px(-16),
28            left: px(12),
29            ..default()
30        },
31        children![Text::new(format!("{}", camera.single().unwrap()))],
32    ));
33}
examples/ui/text/text_background_colors.rs (line 89)
83fn cycle_text_background_colors(
84    time: Res<Time>,
85    children_query: Query<&Children, With<Text>>,
86    mut text_background_colors_query: Query<&mut TextBackgroundColor>,
87) {
88    let n = time.elapsed_secs() as usize;
89    let children = children_query.single().unwrap();
90
91    for (i, child) in children.iter().enumerate() {
92        text_background_colors_query.get_mut(child).unwrap().0 = PALETTE[(i + n) % PALETTE.len()];
93    }
94}
examples/3d/light_textures.rs (line 477)
476fn draw_gizmos(mut gizmos: Gizmos, spotlight: Query<(&GlobalTransform, &SpotLight, &Visibility)>) {
477    if let Ok((global_transform, spotlight, visibility)) = spotlight.single()
478        && visibility != Visibility::Hidden
479    {
480        gizmos.primitive_3d(
481            &Cone::new(7.0 * spotlight.outer_angle, 7.0),
482            Isometry3d {
483                rotation: global_transform.rotation() * Quat::from_rotation_x(FRAC_PI_2),
484                translation: global_transform.translation_vec3a() * 0.5,
485            },
486            YELLOW,
487        );
488    }
489}
examples/camera/pan_orbit_camera_cad.rs (line 119)
104fn toggle_projection(
105    keys: Res<ButtonInput<KeyCode>>,
106    mut dolly: MessageWriter<DollyZoomTrigger>,
107    cam: Query<Entity, With<PanOrbitCamera>>,
108    mut toggled: Local<bool>,
109) {
110    if keys.just_pressed(KeyCode::KeyP) {
111        *toggled = !*toggled;
112        let target_projection = if *toggled {
113            Projection::Orthographic(OrthographicProjection::default_3d())
114        } else {
115            Projection::Perspective(PerspectiveProjection::default())
116        };
117        dolly.write(DollyZoomTrigger {
118            target_projection,
119            camera: cam.single().unwrap(),
120        });
121    }
122}
123
124#[derive(Component)]
125struct ZoomStatusIndicator;
126
127fn zoom_status(zoom_through: bool) -> String {
128    format!("Zoom Through: {zoom_through}")
129}
130
131fn toggle_zoom(
132    keys: Res<ButtonInput<KeyCode>>,
133    mut cam: Query<&mut PanOrbitCamera>,
134    mut text: Query<&mut Text, With<ZoomStatusIndicator>>,
135) {
136    if keys.just_pressed(KeyCode::KeyZ) {
137        let mut editor = cam.single_mut().unwrap();
138        editor.zoom_limits.zoom_through_objects = !editor.zoom_limits.zoom_through_objects;
139        text.single_mut().unwrap().0 = zoom_status(editor.zoom_limits.zoom_through_objects);
140    }
141}
142
143fn toggle_constraint(
144    keys: Res<ButtonInput<KeyCode>>,
145    mut cam: Query<(Entity, &Transform, &mut PanOrbitCamera)>,
146    mut look_to: MessageWriter<LookToTrigger>,
147) {
148    if keys.just_pressed(KeyCode::KeyC) {
149        let (entity, transform, mut editor) = cam.single_mut().unwrap();
150        match editor.orbit_constraint {
151            OrbitConstraint::Fixed { .. } => editor.orbit_constraint = OrbitConstraint::Free,
152            OrbitConstraint::Free => {
153                editor.orbit_constraint = OrbitConstraint::Fixed {
154                    up: DVec3::Y,
155                    can_pass_tdc: false,
156                };
157
158                look_to.write(LookToTrigger::auto_snap_up_direction(
159                    transform.forward().as_dvec3(),
160                    entity,
161                    &transform.rotation.as_dquat(),
162                    editor.as_ref(),
163                ));
164            }
165        };
166    }
167}
168
169fn switch_direction(
170    keys: Res<ButtonInput<KeyCode>>,
171    mut look_to: MessageWriter<LookToTrigger>,
172    cam: Query<(Entity, &Transform, &PanOrbitCamera)>,
173) {
174    let (camera, transform, editor) = cam.single().unwrap();
175    if keys.just_pressed(KeyCode::Digit1) {
176        look_to.write(LookToTrigger::auto_snap_up_direction(
177            DVec3::X,
178            camera,
179            &transform.rotation.as_dquat(),
180            editor,
181        ));
182    }
183    if keys.just_pressed(KeyCode::Digit2) {
184        look_to.write(LookToTrigger::auto_snap_up_direction(
185            DVec3::Z,
186            camera,
187            &transform.rotation.as_dquat(),
188            editor,
189        ));
190    }
191    if keys.just_pressed(KeyCode::Digit3) {
192        look_to.write(LookToTrigger::auto_snap_up_direction(
193            DVec3::NEG_X,
194            camera,
195            &transform.rotation.as_dquat(),
196            editor,
197        ));
198    }
199    if keys.just_pressed(KeyCode::Digit4) {
200        look_to.write(LookToTrigger::auto_snap_up_direction(
201            DVec3::NEG_Z,
202            camera,
203            &transform.rotation.as_dquat(),
204            editor,
205        ));
206    }
207    if keys.just_pressed(KeyCode::Digit5) {
208        look_to.write(LookToTrigger::auto_snap_up_direction(
209            DVec3::Y,
210            camera,
211            &transform.rotation.as_dquat(),
212            editor,
213        ));
214    }
215    if keys.just_pressed(KeyCode::Digit6) {
216        look_to.write(LookToTrigger::auto_snap_up_direction(
217            DVec3::NEG_Y,
218            camera,
219            &transform.rotation.as_dquat(),
220            editor,
221        ));
222    }
223}
examples/ecs/observers.rs (line 196)
190fn handle_click(
191    mouse_button_input: Res<ButtonInput<MouseButton>>,
192    camera: Single<(&Camera, &GlobalTransform)>,
193    windows: Query<&Window>,
194    mut commands: Commands,
195) {
196    let Ok(windows) = windows.single() else {
197        return;
198    };
199
200    let (camera, camera_transform) = *camera;
201    if let Some(pos) = windows
202        .cursor_position()
203        .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor).ok())
204        .map(|ray| ray.origin.truncate())
205        && mouse_button_input.just_pressed(MouseButton::Left)
206    {
207        commands.trigger(ExplodeMines { pos, radius: 1.0 });
208    }
209}
Source

pub fn single_mut( &mut self, ) -> Result<<D as QueryData>::Item<'_, 's>, QuerySingleError>
where D: IterQueryData,

Returns a single query item when there is exactly one entity matching the query.

If the number of query items is not exactly one, a QuerySingleError is returned instead.

§Example
fn regenerate_player_health_system(mut query: Query<&mut Health, With<Player>>) {
    let mut health = query.single_mut().expect("Error: Could not find a single player.");
    health.0 += 1;
}
§See also
  • single to get the read-only query item.
Examples found in repository?
tests/window/desktop_request_redraw.rs (line 98)
97fn update(time: Res<Time>, mut query: Query<&mut Transform, With<AnimationActive>>) {
98    if let Ok(mut transform) = query.single_mut() {
99        transform.rotate_x(time.delta_secs().min(1.0 / 60.0));
100    }
101}
More examples
Hide additional examples
examples/3d/meshlet.rs (line 123)
122fn bunny_wiggler(mut bunny: Query<&mut Transform, With<BunnyWiggler>>, time: Res<Time>) {
123    bunny.single_mut().as_deref_mut().unwrap().translation.z +=
124        ops::cos(time.elapsed_secs() * 10.0) * 0.003;
125}
examples/audio/audio_control.rs (line 89)
85fn mute(
86    keyboard_input: Res<ButtonInput<KeyCode>>,
87    mut music_controller: Query<&mut AudioSink, With<MyMusic>>,
88) {
89    let Ok(mut sink) = music_controller.single_mut() else {
90        return;
91    };
92
93    if keyboard_input.just_pressed(KeyCode::KeyM) {
94        sink.toggle_mute();
95    }
96}
97
98fn volume(
99    keyboard_input: Res<ButtonInput<KeyCode>>,
100    mut music_controller: Query<&mut AudioSink, With<MyMusic>>,
101) {
102    let Ok(mut sink) = music_controller.single_mut() else {
103        return;
104    };
105
106    if keyboard_input.just_pressed(KeyCode::Equal) {
107        let current_volume = sink.volume();
108        sink.set_volume(current_volume.increase_by_percentage(10.0));
109    } else if keyboard_input.just_pressed(KeyCode::Minus) {
110        let current_volume = sink.volume();
111        sink.set_volume(current_volume.increase_by_percentage(-10.0));
112    }
113}
examples/stress_tests/many_text2d.rs (line 170)
169fn move_camera(time: Res<Time>, mut camera_query: Query<&mut Transform, With<Camera>>) {
170    let Ok(mut camera_transform) = camera_query.single_mut() else {
171        return;
172    };
173    camera_transform.rotate_z(time.delta_secs() * 0.5);
174    *camera_transform =
175        *camera_transform * Transform::from_translation(Vec3::X * CAMERA_SPEED * time.delta_secs());
176}
examples/camera/pan_orbit_camera_cad.rs (line 137)
131fn toggle_zoom(
132    keys: Res<ButtonInput<KeyCode>>,
133    mut cam: Query<&mut PanOrbitCamera>,
134    mut text: Query<&mut Text, With<ZoomStatusIndicator>>,
135) {
136    if keys.just_pressed(KeyCode::KeyZ) {
137        let mut editor = cam.single_mut().unwrap();
138        editor.zoom_limits.zoom_through_objects = !editor.zoom_limits.zoom_through_objects;
139        text.single_mut().unwrap().0 = zoom_status(editor.zoom_limits.zoom_through_objects);
140    }
141}
142
143fn toggle_constraint(
144    keys: Res<ButtonInput<KeyCode>>,
145    mut cam: Query<(Entity, &Transform, &mut PanOrbitCamera)>,
146    mut look_to: MessageWriter<LookToTrigger>,
147) {
148    if keys.just_pressed(KeyCode::KeyC) {
149        let (entity, transform, mut editor) = cam.single_mut().unwrap();
150        match editor.orbit_constraint {
151            OrbitConstraint::Fixed { .. } => editor.orbit_constraint = OrbitConstraint::Free,
152            OrbitConstraint::Free => {
153                editor.orbit_constraint = OrbitConstraint::Fixed {
154                    up: DVec3::Y,
155                    can_pass_tdc: false,
156                };
157
158                look_to.write(LookToTrigger::auto_snap_up_direction(
159                    transform.forward().as_dvec3(),
160                    entity,
161                    &transform.rotation.as_dquat(),
162                    editor.as_ref(),
163                ));
164            }
165        };
166    }
167}
examples/asset/multi_asset_sync.rs (line 264)
253fn get_async_loading_state(
254    state: Res<AsyncLoadingState>,
255    mut next_loading_state: ResMut<NextState<LoadingState>>,
256    mut text: Query<&mut Text, With<LoadingText>>,
257) {
258    // Load the value written by the `Future`.
259    let is_loaded = state.0.load(Ordering::Acquire);
260
261    // If loaded, change the state.
262    if is_loaded {
263        next_loading_state.set(LoadingState::Loaded);
264        if let Ok(mut text) = text.single_mut() {
265            "Loaded!".clone_into(&mut **text);
266        }
267    }
268}
Source

pub fn single_inner( self, ) -> Result<<D as QueryData>::Item<'w, 's>, QuerySingleError>
where D: IterQueryData,

Returns a single query item when there is exactly one entity matching the query. This consumes the Query to return results with the actual “inner” world lifetime.

If the number of query items is not exactly one, a QuerySingleError is returned instead.

§Example
fn regenerate_player_health_system(query: Query<&mut Health, With<Player>>) {
    let mut health = query.single_inner().expect("Error: Could not find a single player.");
    health.0 += 1;
}
§See also
  • single to get the read-only query item.
  • single_mut to get the mutable query item.
Examples found in repository?
examples/usage/character_creation.rs (line 249)
245fn on_changed_editable_text(
246    name_input_q: Query<&EditableText, With<NameInput>>,
247    mut character: ResMut<Character>,
248) {
249    let Ok(editable_text) = name_input_q.single_inner() else {
250        return;
251    };
252    let new_name = editable_text.value().to_string();
253    if character.name != new_name {
254        character.name = new_name;
255        character.changed_fields.push(ChangedField::Name);
256    }
257
258    // We do not need to update the ui widget view in our app because `EditableText`
259    // manages its own state internally; it updates the text the user sees automatically.
260
261    // Because character has been modified, refresh_character will run and update the other half of the "View".
262}
263
264// --- END TEXT INPUT -- //
265
266// --- START SLIDER -- //
267
268/// Creates the age slider that allows the user to input the age of the character.
269fn age_slider_row(character: &Character) -> impl Scene {
270    let age = character.age;
271    bsn! {
272        Node {
273            flex_direction: FlexDirection::Row,
274            align_items: AlignItems::Center,
275            justify_content: JustifyContent::SpaceBetween,
276            column_gap: px(10),
277        }
278        Children [
279            Node
280            Children [
281                Text::new("Age:")
282            ]
283            --
284            @age_slider(character)
285            --
286            Node {
287                width: px(30),
288            }
289            Children [
290                AgeSliderText
291                Text(format!("{}", age))
292            ]
293        ]
294    }
295}
296
297fn age_slider(character: &Character) -> impl Scene {
298    bsn! {
299        Node {
300            width: px(220),
301            border: px(5),
302            padding: UiRect::axes(px(5), px(2)),
303        }
304        AgeSlider
305        Slider {
306            track_click: TrackClick::Snap,
307            orientation: SliderOrientation::Horizontal,
308        }
309        SliderValue({character.age as f32})
310        // Move every whole number.
311        SliderPrecision(0)
312        SliderRange::new(1., 100.)
313        BackgroundColor(Color::BLACK)
314        // This observer is part of the Controller -- it reacts to the user's input!
315        on(on_value_change_age_slider)
316        on(on_pointer_over_pointer_cursor)
317        on(on_pointer_drag_start_grabbing_cursor)
318        on(on_pointer_drag_end_grab_cursor)
319        on(on_pointer_out_default_cursor)
320        Children [
321            // Visible Slider Track
322            // It is 220px in width via its parent.
323            Node {
324                height: px(5),
325                border_radius: BorderRadius::all(px(3)),
326            }
327            BackgroundColor(Color::BLACK)
328            --
329            // Invisible shorter track (does not have background color) that the
330            // SliderThumb glides on. This is so that the thumb
331            // does not go past the left and right sides of the visible slider track.
332            Node {
333                display: Display::Flex,
334                position_type: PositionType::Absolute,
335                left: px(0)
336                // Shortened by the slider thumb's width on the right side.
337                // This means that it is 200px in width.
338                right: px(20),
339                top: px(0),
340                bottom: px(0),
341            }
342            Children [
343                AgeSliderThumb
344                SliderThumb
345                Node {
346                    display: Display::Flex,
347                    width: px(20),
348                    height: px(10),
349                    position_type: PositionType::Absolute,
350                    // Where the thumb is along the track will be updated by `on_value_change_age_slider`
351                    left: percent((character.age as f32 - 1.) / (100. - 1.) * 100.),
352                }
353                BackgroundColor(Color::WHITE)
354                on(on_pointer_over_grab_cursor)
355                on(on_pointer_out_default_cursor)
356                on(on_pointer_drag_start_grabbing_cursor)
357                on(on_pointer_drag_end_grab_cursor)
358            ]
359        ]
360    }
361}
362
363/// A system that implements Controller logic to update the Age.
364/// This particular system updates the Model upon any change in value to the Age Slider.
365/// Sliders emit a `ValueChange<f32>` event when the user drags the slider.
366/// The value of the event is the new value of the slider.
367/// The source of the event is the `Slider` parent entity.
368fn on_value_change_age_slider(
369    event: On<ValueChange<f32>>,
370    age_slider_q: Query<(Entity, &SliderRange), With<AgeSlider>>,
371    mut age_slider_text_q: Query<&mut Text, With<AgeSliderText>>,
372    mut age_slider_thumb_q: Query<&mut Node, With<AgeSliderThumb>>,
373    mut character: ResMut<Character>,
374    mut commands: Commands,
375) {
376    let Ok((entity, slider_range)) = age_slider_q.single_inner() else {
377        return;
378    };
379    if event.source != entity {
380        return;
381    }
382
383    // Update the Model
384    // `SliderPrecision` ensures that this value is a whole number.
385    character.age = event.value as u32;
386    character.changed_fields.push(ChangedField::Age);
387
388    // Update the Widget portion of the View
389    commands
390        .entity(event.source)
391        .insert(SliderValue(character.age as f32));
392    for mut node in age_slider_thumb_q.iter_mut() {
393        node.left = percent(slider_range.thumb_position(character.age as f32) * 100.0);
394    }
395    for mut text in age_slider_text_q.iter_mut() {
396        *text = Text::new(format!("{}", character.age));
397    }
398
399    // Because character has been modified, refresh_character will run and update the other half of the "View".
400}
401
402// --- END SLIDER -- //
403
404// --- START RADIO GROUP -- //
405
406/// Creates the radio group row that allows the user to select a hat for the character.
407fn hat_type_radio_group_row(character: &Character) -> impl Scene {
408    bsn! {
409        Node {
410            flex_direction: FlexDirection::Row,
411            align_items: AlignItems::Center,
412            justify_content: JustifyContent::SpaceBetween,
413        }
414        RadioGroup
415        HatTypeRadioGroup
416        // This observer is part of the Controller -- it reacts to the user's input!
417        on(on_value_change_hat_type)
418        Children [
419            Node
420            Children [
421                Text("Hat: ")
422            ]
423            --
424            {
425                HAT_TYPES.iter()
426                    .map(|hat_type| hat_type_radio_button(*hat_type, character))
427                    .collect::<Vec<_>>()
428            }
429        ]
430    }
431}
432
433fn hat_type_radio_button(hat_type: HatType, character: &Character) -> Box<dyn Scene> {
434    let base_radio_button = || {
435        bsn! {
436            Node {
437                border: px(5),
438                border_radius: BorderRadius::all(px(10)),
439                padding: UiRect::axes(px(5), px(2)),
440            }
441            RadioButton
442            hat_type
443            BackgroundColor(Color::BLACK)
444            on(on_pointer_over_pointer_cursor)
445            on(on_pointer_out_default_cursor)
446        }
447    };
448    if character.hat_type == hat_type {
449        Box::new(bsn! {
450            @base_radio_button()
451            // The selected hat_type must have the `Checked` component.
452            Checked
453            Children [
454                Text::new(format!("{hat_type:?}"))
455                // The selected hat_type's text is green as opposed to white.
456                TextColor(palettes::basic::GREEN)
457            ]
458        })
459    } else {
460        Box::new(bsn! {
461            @base_radio_button()
462            Children [
463                Text(format!("{hat_type:?}"))
464                TextColor(palettes::basic::WHITE)
465            ]
466        })
467    }
468}
469
470/// This observer is part of the Controller logic.
471/// This observer will update the `Character` Resource based on a change to the Hat Type Radio Group.
472/// Radio groups emit a `ValueChange<Entity>` event when the user clicks on a radio button.
473/// The value of the event is of the clicked radio button.
474/// The source of the event is the parent radio group.
475fn on_value_change_hat_type(
476    event: On<ValueChange<Entity>>,
477    hat_type_value_q: Query<(Entity, &HatType, Has<Checked>, &Children), With<RadioButton>>,
478    hat_type_radio_group_q: Single<Entity, With<HatTypeRadioGroup>>,
479    mut character: ResMut<Character>,
480    mut commands: Commands,
481) {
482    // Ensure this value change event is for the Hat Type Radio Group
483    // Although unnecessary in this example, apps with multiple radio groups need to distinguish
484    // what the value change is for.
485    if event.source != hat_type_radio_group_q.entity() {
486        return;
487    }
488
489    let Ok((_, new_hat_type, has_checked, _)) = hat_type_value_q.get(event.value) else {
490        return;
491    };
492
493    if has_checked {
494        // The hat type has actually not changed, so we do not need to do anything.
495        return;
496    }
497
498    // Update the Model
499    character.hat_type = *new_hat_type;
500    character.changed_fields.push(ChangedField::HatType);
501
502    // Update the Widget portion of the View
503    for (button_entity, hat_type, has_checked, children) in hat_type_value_q.iter() {
504        if character.hat_type == *hat_type {
505            commands.entity(button_entity).insert(Checked);
506            // The radio button only has one child for the text and color of the button
507            commands
508                .entity(children[0])
509                .insert(TextColor(palettes::basic::GREEN.into()));
510        } else if has_checked {
511            commands.entity(button_entity).remove::<Checked>();
512            commands.entity(children[0]).insert(TextColor(Color::WHITE));
513        }
514    }
515    // Because character has been modified, refresh_character will run and update the other half of the "View".
516}
517
518// --- END RADIO GROUP -- //
519
520// --- START CHECK BOX -- //
521
522/// Creates the checkbox row that allows the user to toggle a yellow tint of the character.
523fn tint_yellow_checkbox_row(character: &Character) -> impl Scene {
524    bsn! {
525        Node {
526            flex_direction: FlexDirection::Row,
527            align_items: AlignItems::Center,
528            justify_content: JustifyContent::SpaceBetween,
529        }
530        Children [
531            Node
532            Children [
533                Text("Tint Yellow: ")
534            ]
535            --
536            @tint_yellow_checkbox(character)
537        ]
538    }
539}
540
541fn tint_yellow_checkbox(character: &Character) -> Box<dyn Scene> {
542    let base_checkbox = || {
543        bsn! {
544            Node {
545                padding: UiRect::horizontal(px(5)),
546            }
547            Checkbox
548            TintYellowCheckbox
549            BackgroundColor(Color::WHITE)
550            on(on_pointer_over_pointer_cursor)
551            on(on_pointer_out_default_cursor)
552            // This observer is part of the controller -- it reacts to the user's input!
553            on(on_value_change_tint_yellow)
554        }
555    };
556
557    if character.tint_yellow {
558        Box::new(bsn! {
559            @base_checkbox()
560            Checked
561            Children [
562                Text("X")
563                TextColor(palettes::basic::GREEN)
564            ]
565        })
566    } else {
567        Box::new(bsn! {
568            @base_checkbox()
569            Children [
570                Text(" ")
571                TextColor(palettes::basic::GREEN)
572            ]
573        })
574    }
575}
576
577/// This observer is part of the Controller logic.
578/// This observer will update the `Character` Resource based on a change to the Tint Yellow Checkbox.
579/// Checkboxes emit a `ValueChange<bool>` event when the user clicks on a checkbox.
580/// The value of the event is the value of the toggle.
581/// The source of the event is the checkbox.
582fn on_value_change_tint_yellow(
583    event: On<ValueChange<bool>>,
584    tint_yellow_checkbox_q: Query<(Entity, &Children), With<TintYellowCheckbox>>,
585    mut character: ResMut<Character>,
586    mut commands: Commands,
587) {
588    let Ok((checkbox_entity, children)) = tint_yellow_checkbox_q.single_inner() else {
589        return;
590    };
591
592    // Ensure this value change event is for the checkbox.
593    // Although unnecessary in this example, apps with multiple checkboxes need to distinguish
594    // what the value change is for.
595    if event.source != checkbox_entity {
596        return;
597    }
598
599    // Update the Model
600    character.tint_yellow = event.value;
601    character.changed_fields.push(ChangedField::TintYellow);
602
603    // Update the Widget portion of the View
604    if character.tint_yellow {
605        commands.entity(event.source).insert(Checked);
606        // The checkbox only has one child for the X and its color
607        commands.entity(children[0]).insert(Text::new("X"));
608    } else {
609        commands.entity(event.source).remove::<Checked>();
610        commands.entity(children[0]).insert(Text::new(" "));
611    }
612    // Because character has been modified, refresh_character will run and update the other half of the "View".
613}
Source

pub fn is_empty(&self) -> bool

Returns true if there are no query items.

This is equivalent to self.iter().next().is_none(), and thus the worst case runtime will be O(n) where n is the number of potential matches. This can be notably expensive for queries that rely on non-archetypal filters such as Added, Changed or Spawned which must individually check each query result for a match.

§Example

Here, the score is increased only if an entity with a Player component is present in the world:

fn update_score_system(query: Query<(), With<Player>>, mut score: ResMut<Score>) {
    if !query.is_empty() {
        score.0 += 1;
    }
}
Examples found in repository?
examples/usage/context_menu.rs (line 74)
66fn setup(mut commands: Commands) {
67    commands.spawn(Camera2d);
68
69    commands.spawn_scene(bsn! {
70        @background()
71        on(|press: On<PointerPress>, query: Query<(), With<ContextMenu>>, mut commands: Commands| {
72            debug!("click: {}", press.pointer.position);
73
74            if query.is_empty() {
75                // Open the context menu at the pointer location if one does not exist
76                commands.trigger(OpenContextMenu {
77                    pos: press.pointer.position,
78                });
79            } else {
80                // Close the context menu if it exists
81                commands.trigger(CloseContextMenus);
82            }
83        })
84    });
85}
More examples
Hide additional examples
examples/3d/mirror.rs (line 595)
583fn play_fox_animation(
584    mut commands: Commands,
585    mut animation_players_query: Query<
586        (Entity, &mut AnimationPlayer),
587        Without<AnimationGraphHandle>,
588    >,
589    asset_server: Res<AssetServer>,
590    mut animation_graphs: ResMut<Assets<AnimationGraph>>,
591) {
592    // Only pick up animation players that don't already have an animation graph
593    // handle.
594    // This ensures that we only start playing the animation once.
595    if animation_players_query.is_empty() {
596        return;
597    }
598
599    let fox_animation = asset_server.load(GltfAssetLabel::Animation(0).from_asset(FOX_ASSET_PATH));
600    let (fox_animation_graph, fox_animation_node) =
601        AnimationGraph::from_clip(fox_animation.clone());
602    let fox_animation_graph = animation_graphs.add(fox_animation_graph);
603
604    for (entity, mut animation_player) in animation_players_query.iter_mut() {
605        commands
606            .entity(entity)
607            .insert(AnimationGraphHandle(fox_animation_graph.clone()));
608        animation_player.play(fox_animation_node).repeat();
609    }
610}
examples/3d/solari_reflections.rs (line 857)
814fn update_control_text(
815    mut rows: Query<(&ControlRow, &mut Text)>,
816    state: Res<DemoState>,
817    pathtracing: Query<(), With<Pathtracer>>,
818    #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] dlss_rr_supported: Option<
819        Res<DlssRayReconstructionSupported>,
820    >,
821    #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] dlss_camera: Query<
822        Has<Dlss<DlssRayReconstructionFeature>>,
823        With<SolariLighting>,
824    >,
825) {
826    for (row, mut text) in &mut rows {
827        text.0.clear();
828
829        match row {
830            ControlRow::Pause => text
831                .0
832                .push_str(if state.paused { "Resume" } else { "Pause" }),
833            ControlRow::Metallic => text.0.push_str(if state.metallic {
834                "Switch to dielectric"
835            } else {
836                "Switch to metallic"
837            }),
838            ControlRow::Presets => {
839                for (_, name, roughness) in MATERIAL_PRESETS {
840                    if (roughness - state.roughness).abs() < 1e-4 {
841                        text.0.push_str(&format!("[{name}] "));
842                    } else {
843                        text.0.push_str(&format!("{name} "));
844                    }
845                }
846            }
847            ControlRow::MirrorPan => text.0.push_str(if state.pan_mirror {
848                "Stop panning"
849            } else {
850                "Pan back and forth"
851            }),
852            ControlRow::MirrorSlide => text.0.push_str(if state.slide_mirror {
853                "Stop sliding"
854            } else {
855                "Slide back and forth"
856            }),
857            ControlRow::Renderer => text.0.push_str(if pathtracing.is_empty() {
858                "Switch to reference pathtracer"
859            } else {
860                "Switch to realtime lighting  -  pause to let the pathtracer converge"
861            }),
862            ControlRow::Denoising => {
863                #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
864                if dlss_rr_supported.is_some() {
865                    if matches!(dlss_camera.single(), Ok(true)) {
866                        text.0.push_str("Disable DLSS Ray Reconstruction");
867                    } else {
868                        text.0.push_str("Enable DLSS Ray Reconstruction");
869                    }
870                } else {
871                    text.0.push_str("DLSS Ray Reconstruction not supported");
872                }
873
874                #[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))]
875                text.0.push_str("App not compiled with DLSS support");
876            }
877        }
878    }
879}
880
881fn update_performance_text(
882    mut text: Single<&mut Text, With<PerformanceText>>,
883    diagnostics: Res<DiagnosticsStore>,
884    pathtracing: Query<(), With<Pathtracer>>,
885    #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] dlss_camera: Query<
886        Has<Dlss<DlssRayReconstructionFeature>>,
887        With<SolariLighting>,
888    >,
889) {
890    text.0.clear();
891
892    if !pathtracing.is_empty() {
893        text.push_str("Pathtracer (untimed)");
894        return;
895    }
896
897    let mut total = 0.0;
898    let mut add_diagnostic = |name: &str, path: &'static str| {
899        let path = DiagnosticPath::new(path);
900        if let Some(value) = diagnostics.get(&path).and_then(Diagnostic::smoothed) {
901            text.push_str(&format!("{name:17}  {value:.2} ms\n"));
902            total += value;
903        }
904    };
905
906    (add_diagnostic)(
907        "Light tiles",
908        "render/solari_lighting/presample_light_tiles/elapsed_gpu",
909    );
910    (add_diagnostic)(
911        "World cache",
912        "render/solari_lighting/world_cache/elapsed_gpu",
913    );
914    (add_diagnostic)("Lighting", "render/solari_lighting/lighting/elapsed_gpu");
915    #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]
916    if matches!(dlss_camera.single(), Ok(true)) {
917        (add_diagnostic)("DLSS-RR", "render/dlss_ray_reconstruction/elapsed_gpu");
918    }
919    text.push_str(&format!("{:17}  {total:.2} ms\n", "Total"));
920}
examples/3d/irradiance_volumes.rs (line 538)
528fn create_cubes(
529    image_assets: Res<Assets<Image>>,
530    mut commands: Commands,
531    irradiance_volumes: Query<(&IrradianceVolume, &GlobalTransform)>,
532    voxel_cube_parents: Query<Entity, With<VoxelCubeParent>>,
533    voxel_cubes: Query<Entity, With<VoxelCube>>,
534    example_assets: Res<ExampleAssets>,
535    mut voxel_visualization_material_assets: ResMut<Assets<VoxelVisualizationMaterial>>,
536) {
537    // If voxel cubes have already been spawned, don't do anything.
538    if !voxel_cubes.is_empty() {
539        return;
540    }
541
542    let Some(voxel_cube_parent) = voxel_cube_parents.iter().next() else {
543        return;
544    };
545
546    for (irradiance_volume, global_transform) in irradiance_volumes.iter() {
547        let Some(image) = image_assets.get(&irradiance_volume.voxels) else {
548            continue;
549        };
550
551        let resolution = image.texture_descriptor.size;
552
553        let voxel_cube_material = voxel_visualization_material_assets.add(ExtendedMaterial {
554            base: StandardMaterial::from(Color::from(RED)),
555            extension: VoxelVisualizationExtension {
556                irradiance_volume_info: VoxelVisualizationIrradianceVolumeInfo {
557                    world_from_voxel: VOXEL_FROM_WORLD.inverse(),
558                    voxel_from_world: VOXEL_FROM_WORLD,
559                    resolution: uvec3(
560                        resolution.width,
561                        resolution.height,
562                        resolution.depth_or_array_layers,
563                    ),
564                    intensity: IRRADIANCE_VOLUME_INTENSITY,
565                },
566            },
567        });
568
569        let scale = vec3(
570            1.0 / resolution.width as f32,
571            1.0 / resolution.height as f32,
572            1.0 / resolution.depth_or_array_layers as f32,
573        );
574
575        // Spawn a cube for each voxel.
576        for z in 0..resolution.depth_or_array_layers {
577            for y in 0..resolution.height {
578                for x in 0..resolution.width {
579                    let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
580                    let pos = global_transform.transform_point(uvw);
581                    let voxel_cube = commands
582                        .spawn((
583                            Mesh3d(example_assets.voxel_cube.clone()),
584                            MeshMaterial3d(voxel_cube_material.clone()),
585                            Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
586                                .with_translation(pos),
587                        ))
588                        .insert(VoxelCube)
589                        .insert(NotShadowCaster)
590                        .id();
591
592                    commands.entity(voxel_cube_parent).add_child(voxel_cube);
593                }
594            }
595        }
596    }
597}
Source

pub fn contains(&self, entity: Entity) -> bool

Returns true if the given Entity matches the query.

This is always guaranteed to run in O(1) time.

§Example
fn targeting_system(in_range_query: Query<&InRange>, target: Res<Target>) {
    if in_range_query.contains(target.entity) {
        println!("Bam!")
    }
}
Examples found in repository?
examples/2d/dynamic_mip_generation.rs (line 462)
457fn handle_regenerate_top_mip_level_activate(
458    event: On<Activate>,
459    q: Query<(), With<RegenerateTopMipLevelButton>>,
460    mut regenerate_image_message_writer: MessageWriter<RegenerateImage>,
461) {
462    if q.contains(event.entity) {
463        // Schedule the image to be regenerated.
464        regenerate_image_message_writer.write(RegenerateImage);
465    }
466}
More examples
Hide additional examples
examples/testbed/3d.rs (line 498)
490    pub fn show_aabbs(
491        scene_ready: On<WorldInstanceReady>,
492        mut commands: Commands,
493        children: Query<&Children>,
494        meshes: Query<(), With<Mesh3d>>,
495    ) {
496        for child in children
497            .iter_descendants(scene_ready.entity)
498            .filter(|&e| meshes.contains(e))
499        {
500            commands.entity(child).insert(ShowAabbGizmo {
501                color: Some(BLACK.into()),
502            });
503        }
504    }
examples/ui/widgets/viewport_node.rs (line 107)
98fn draw_mesh_intersections(
99    pointers: Query<&PointerInteraction>,
100    untargetable: Query<Entity, Without<Shape>>,
101    mut gizmos: Gizmos,
102) {
103    for (point, normal) in pointers
104        .iter()
105        .flat_map(|interaction| interaction.iter())
106        .filter_map(|(entity, hit)| {
107            if !untargetable.contains(*entity) {
108                hit.position.zip(hit.normal)
109            } else {
110                None
111            }
112        })
113    {
114        gizmos.arrow(point, point + normal.normalize() * 0.5, Color::WHITE);
115    }
116}
examples/ecs/entity_disabling.rs (line 46)
38fn disable_entities_on_click(
39    click: On<PointerClick>,
40    valid_query: Query<&DisableOnClick>,
41    mut commands: Commands,
42) {
43    // Windows and text are entities and can be clicked!
44    // We definitely don't want to disable the window itself,
45    // because that would cause the app to close!
46    if valid_query.contains(click.entity) {
47        // Just add the `Disabled` component to the entity to disable it.
48        // Note that the `Disabled` component is *only* added to the entity,
49        // its children are not affected.
50        commands.entity(click.entity).insert(Disabled);
51    }
52}
examples/asset/asset_saving.rs (line 287)
281fn on_press_selectable(
282    event: On<PointerPress>,
283    mut borders: Query<(Entity, &mut BorderColor, &BackgroundColor), With<SelectableColor>>,
284    mut draw_color: ResMut<DrawColor>,
285    mut commands: Commands,
286) {
287    if !borders.contains(event.entity) {
288        return;
289    }
290    for (entity, mut border, _) in borders.iter_mut() {
291        commands.entity(entity).remove::<Selected>();
292        *border = BorderColor::all(NORMAL_COLOR);
293    }
294    let (_, mut border, background_color) = borders.get_mut(event.entity).unwrap();
295    *border = BorderColor::all(SELECTED_COLOR);
296    commands.entity(event.entity).insert(Selected);
297
298    draw_color.0 = background_color.0;
299}
examples/asset/asset_saving_with_subassets.rs (line 274)
265fn spawn_box(
266    press: On<PointerPress>,
267    window: Query<(), With<Window>>,
268    camera: Single<(&Camera, &GlobalTransform)>,
269    mut commands: Commands,
270) {
271    if press.button != PointerButton::Primary {
272        return;
273    }
274    if !window.contains(press.entity) {
275        return;
276    }
277
278    let (camera, camera_transform) = camera.into_inner();
279    let Ok(click_point) = camera.viewport_to_world_2d(camera_transform, press.pointer.position)
280    else {
281        return;
282    };
283    commands.spawn((
284        Sprite::from_color(tailwind::RED_500, Vec2::new(100.0, 100.0)),
285        Transform::from_translation(click_point.extend(0.0)),
286        Pickable::default(),
287        Box,
288    ));
289}
290
291/// A component to rotate the hue of a sprite every frame.
292#[derive(Component)]
293struct RotateHue;
294
295/// Rotates the hue of each [`Sprite`] tagged with [`RotateHue`].
296fn rotate_hue(time: Res<Time>, mut sprites: Query<&mut Sprite, With<RotateHue>>) {
297    for mut sprite in sprites.iter_mut() {
298        // Make a full rotation every 2 seconds.
299        sprite.color = sprite.color.rotate_hue(time.delta_secs() * 180.0);
300    }
301}
302
303/// Starts rotating the hue of a box that has been right-clicked.
304fn start_rotate_box_hue(
305    event: On<PointerPress>,
306    boxes: Query<(), With<Box>>,
307    mut commands: Commands,
308) {
309    if event.button != PointerButton::Secondary {
310        return;
311    }
312    if !boxes.contains(event.entity) {
313        return;
314    }
315    commands.entity(event.entity).insert(RotateHue);
316}
317
318/// Stops rotating the box hue if it's right-click is released.
319fn end_rotate_box_hue_on_release(
320    event: On<PointerRelease>,
321    boxes: Query<(), (With<Box>, With<RotateHue>)>,
322    mut commands: Commands,
323) {
324    if event.button != PointerButton::Secondary {
325        return;
326    }
327    if !boxes.contains(event.entity) {
328        return;
329    }
330    commands.entity(event.entity).remove::<RotateHue>();
331}
332
333/// Stops rotating the box hue if the cursor moves off the entity.
334fn end_rotate_box_hue_on_out(
335    event: On<PointerOut>,
336    boxes: Query<(), (With<Box>, With<RotateHue>)>,
337    mut commands: Commands,
338) {
339    if !boxes.contains(event.entity) {
340        return;
341    }
342    commands.entity(event.entity).remove::<RotateHue>();
343}
344
345/// Blocks propagation of pointer press events on left-clicked boxes.
346fn stop_propagate_on_clicked_box(mut event: On<PointerPress>, boxes: Query<(), With<Box>>) {
347    if event.button != PointerButton::Primary {
348        return;
349    }
350    if !boxes.contains(event.entity) {
351        return;
352    }
353    event.propagate(false);
354}
Source

pub fn count(&self) -> usize

Counts the number of entities that match the query.

This is equivalent to self.iter().count() but may be more efficient in some cases.

If D::IS_ARCHETYPAL && F::IS_ARCHETYPAL is true, this will do work proportional to the number of matched archetypes or tables, but will not iterate each entity. If it is false, it will have to do work for each entity.

§Example
fn targeting_system(in_range_query: Query<&InRange>) {
    let count = in_range_query.count();
    println!("{count} targets in range!");
}
Source

pub fn transmute_lens<NewD>(&mut self) -> QueryLens<'_, NewD>

Returns a QueryLens that can be used to construct a new Query giving more restrictive access to the entities matched by the current query.

A transmute is valid only if NewD has a subset of the read, write, and required access of the current query. A precise description of the access required by each parameter type is given in the table below, but typical uses are to:

  • Remove components, e.g. Query<(&A, &B)> to Query<&A>.
  • Retrieve an existing component with reduced or equal access, e.g. Query<&mut A> to Query<&A> or Query<&T> to Query<Ref<T>>.
  • Add parameters with no new access, for example adding an Entity parameter.

Note that since filter terms are dropped, non-archetypal filters like Added, Changed and Spawned will not be respected. To maintain or change filter terms see Self::transmute_lens_filtered.

QueryData parameter typeAccess required
Entity, EntityLocation, SpawnDetails, &Archetype, Has<T>, PhantomData<T>No access
EntityMutRead and write access to all components, but no required access
EntityRefRead access to all components, but no required access
&T, Ref<T>Read and required access to T
&mut T, Mut<T>Read, write and required access to T
Option<T>, AnyOf<(D, ...)>Read and write access to T, but no required access
Tuples of query data and
#[derive(QueryData)] structs
The union of the access of their subqueries
FilteredEntityRef, FilteredEntityMutDetermined by the QueryBuilder used to construct them. Any query can be transmuted to them, and they will receive the access of the source query. When combined with other QueryData, they will receive any access of the source query that does not conflict with the other data

transmute_lens drops filter terms, but Self::transmute_lens_filtered supports returning a QueryLens with a new filter type - the access required by filter parameters are as follows.

QueryFilter parameter typeAccess required
Added<T>, Changed<T>Read and required access to T
With<T>, Without<T>No access
Or<(T, ...)>Read access of the subqueries, but no required access
Tuples of query filters and #[derive(QueryFilter)] structsThe union of the access of their subqueries
§Panics

This will panic if the access required by NewD is not a subset of that required by the original fetch D.

§Example
fn reusable_function(lens: &mut QueryLens<&A>) {
    assert_eq!(lens.query().single().unwrap().0, 10);
}

// We can use the function in a system that takes the exact query.
fn system_1(mut query: Query<&A>) {
    reusable_function(&mut query.as_query_lens());
}

// We can also use it with a query that does not match exactly
// by transmuting it.
fn system_2(mut query: Query<(&mut A, &B)>) {
    let mut lens = query.transmute_lens::<&A>();
    reusable_function(&mut lens);
}
§Examples of valid transmutes
// `&mut T` and `Mut<T>` access the same data and can be transmuted to each other,
// `&T` and `Ref<T>` access the same data and can be transmuted to each other,
// and mutable versions can be transmuted to read-only versions
assert_valid_transmute::<&mut T, &T>();
assert_valid_transmute::<&mut T, Mut<T>>();
assert_valid_transmute::<Mut<T>, &mut T>();
assert_valid_transmute::<&T, Ref<T>>();
assert_valid_transmute::<Ref<T>, &T>();

// The structure can be rearranged, or subqueries dropped
assert_valid_transmute::<(&T, &U), &T>();
assert_valid_transmute::<((&T, &U), &V), (&T, (&U, &V))>();
assert_valid_transmute::<Option<(&T, &U)>, (Option<&T>, Option<&U>)>();

// Queries with no access can be freely added
assert_valid_transmute::<
    &T,
    (&T, Entity, EntityLocation, &Archetype, Has<U>, PhantomData<T>),
>();

// Required access can be transmuted to optional,
// and optional access can be transmuted to other optional access
assert_valid_transmute::<&T, Option<&T>>();
assert_valid_transmute::<AnyOf<(&mut T, &mut U)>, Option<&T>>();
// Note that removing subqueries from `AnyOf` will result
// in an `AnyOf` where all subqueries can yield `None`!
assert_valid_transmute::<AnyOf<(&T, &U, &V)>, AnyOf<(&T, &U)>>();
assert_valid_transmute::<EntityMut, Option<&mut T>>();

// Anything can be transmuted to `FilteredEntityRef` or `FilteredEntityMut`
// This will create a `FilteredEntityMut` that only has read access to `T`
assert_valid_transmute::<&T, FilteredEntityMut>();
// This will create a `FilteredEntityMut` that has no access to `T`,
// read access to `U`, and write access to `V`.
assert_valid_transmute::<(&mut T, &mut U, &mut V), (&mut T, &U, FilteredEntityMut)>();

// `Added<T>` and `Changed<T>` filters have the same access as `&T` data
// Remember that they are only evaluated on the transmuted query, not the original query!
assert_valid_transmute_filtered::<Entity, Changed<T>, &T, ()>();
assert_valid_transmute_filtered::<&mut T, (), &T, Added<T>>();
// Nested inside of an `Or` filter, they have the same access as `Option<&T>`.
assert_valid_transmute_filtered::<Option<&T>, (), Entity, Or<(Changed<T>, With<U>)>>();
Source

pub fn transmute_lens_inner<NewD>(self) -> QueryLens<'w, NewD>

Returns a QueryLens that can be used to construct a new Query giving more restrictive access to the entities matched by the current query.

This consumes the Query to return results with the actual “inner” world lifetime.

See Self::transmute_lens for a description of allowed transmutes.

§Panics

This will panic if NewD is not a subset of the original fetch D

§Example
fn reusable_function(mut lens: QueryLens<&A>) {
    assert_eq!(lens.query().single().unwrap().0, 10);
}

// We can use the function in a system that takes the exact query.
fn system_1(query: Query<&A>) {
    reusable_function(query.into_query_lens());
}

// We can also use it with a query that does not match exactly
// by transmuting it.
fn system_2(query: Query<(&mut A, &B)>) {
    let mut lens = query.transmute_lens_inner::<&A>();
    reusable_function(lens);
}
§See also
Source

pub fn transmute_lens_filtered<NewD, NewF>( &mut self, ) -> QueryLens<'_, NewD, NewF>

Equivalent to Self::transmute_lens but also includes a QueryFilter type.

See Self::transmute_lens for a description of allowed transmutes.

Note that the lens will iterate the same tables and archetypes as the original query. This means that additional archetypal query terms like With and Without will not necessarily be respected and non-archetypal terms like Added, Changed and Spawned will only be respected if they are in the type signature.

Source

pub fn transmute_lens_filtered_inner<NewD, NewF>( self, ) -> QueryLens<'w, NewD, NewF>

Equivalent to Self::transmute_lens_inner but also includes a QueryFilter type. This consumes the Query to return results with the actual “inner” world lifetime.

See Self::transmute_lens for a description of allowed transmutes.

Note that the lens will iterate the same tables and archetypes as the original query. This means that additional archetypal query terms like With and Without will not necessarily be respected and non-archetypal terms like Added, Changed and Spawned will only be respected if they are in the type signature.

§See also
Source

pub fn as_query_lens(&mut self) -> QueryLens<'_, D>

Gets a QueryLens with the same accesses as the existing query

Source

pub fn into_query_lens(self) -> QueryLens<'w, D>

Gets a QueryLens with the same accesses as the existing query

§See also
Source

pub fn join<'a, OtherD, NewD>( &'a mut self, other: &'a mut Query<'_, '_, OtherD>, ) -> QueryLens<'a, NewD>
where OtherD: QueryData, NewD: SingleEntityQueryData,

Returns a QueryLens that can be used to get a query with the combined fetch.

For example, this can take a Query<&A> and a Query<&B> and return a Query<(&A, &B)>. The returned query will only return items with both A and B. Note that since filters are dropped, non-archetypal filters like Added, Changed and Spawned will not be respected. To maintain or change filter terms see Self::join_filtered.

§Example

fn system(
    mut transforms: Query<&Transform>,
    mut players: Query<&Player>,
    mut enemies: Query<&Enemy>
) {
    let mut players_transforms: QueryLens<(&Transform, &Player)> = transforms.join(&mut players);
    for (transform, player) in &players_transforms.query() {
        // do something with a and b
    }

    let mut enemies_transforms: QueryLens<(&Transform, &Enemy)> = transforms.join(&mut enemies);
    for (transform, enemy) in &enemies_transforms.query() {
        // do something with a and b
    }
}
§Panics

This will panic if NewD is not a subset of the union of the original fetch Q and OtherD.

§Allowed Transmutes

Like transmute_lens the query terms can be changed with some restrictions. See Self::transmute_lens for more details.

Source

pub fn join_inner<OtherD, NewD>( self, other: Query<'w, '_, OtherD>, ) -> QueryLens<'w, NewD>
where OtherD: QueryData, NewD: SingleEntityQueryData,

Returns a QueryLens that can be used to get a query with the combined fetch. This consumes the Query to return results with the actual “inner” world lifetime.

For example, this can take a Query<&A> and a Query<&B> and return a Query<(&A, &B)>. The returned query will only return items with both A and B. Note that since filters are dropped, non-archetypal filters like Added, Changed and Spawned will not be respected. To maintain or change filter terms see Self::join_filtered.

§Panics

This will panic if NewD is not a subset of the union of the original fetch Q and OtherD.

§Allowed Transmutes

Like transmute_lens the query terms can be changed with some restrictions. See Self::transmute_lens for more details.

§See also
  • join to join using a mutable borrow of the Query.
Source

pub fn join_filtered<'a, OtherD, OtherF, NewD, NewF>( &'a mut self, other: &'a mut Query<'_, '_, OtherD, OtherF>, ) -> QueryLens<'a, NewD, NewF>
where OtherD: QueryData, OtherF: QueryFilter, NewD: SingleEntityQueryData, NewF: QueryFilter,

Equivalent to Self::join but also includes a QueryFilter type.

Note that the lens with iterate a subset of the original queries’ tables and archetypes. This means that additional archetypal query terms like With and Without will not necessarily be respected and non-archetypal terms like Added, Changed and Spawned will only be respected if they are in the type signature.

Source

pub fn join_filtered_inner<OtherD, OtherF, NewD, NewF>( self, other: Query<'w, '_, OtherD, OtherF>, ) -> QueryLens<'w, NewD, NewF>
where OtherD: QueryData, OtherF: QueryFilter, NewD: SingleEntityQueryData, NewF: QueryFilter,

Equivalent to Self::join_inner but also includes a QueryFilter type. This consumes the Query to return results with the actual “inner” world lifetime.

Note that the lens with iterate a subset of the original queries’ tables and archetypes. This means that additional archetypal query terms like With and Without will not necessarily be respected and non-archetypal terms like Added, Changed and Spawned will only be respected if they are in the type signature.

§See also

Trait Implementations§

Source§

impl<D, F> Clone for Query<'_, '_, D, F>

Source§

fn clone(&self) -> Query<'_, '_, D, F>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<D, F> Copy for Query<'_, '_, D, F>

Source§

impl<D, F> Debug for Query<'_, '_, D, F>
where D: QueryData, F: QueryFilter,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'w, 'q, Q, F> From<&'q mut Query<'w, '_, Q, F>> for QueryLens<'q, Q, F>

Source§

fn from(value: &'q mut Query<'w, '_, Q, F>) -> QueryLens<'q, Q, F>

Converts to this type from the input type.
Source§

impl<'w, 's, Q, F> From<&'s mut QueryLens<'w, Q, F>> for Query<'s, 's, Q, F>
where Q: QueryData, F: QueryFilter,

Source§

fn from(value: &'s mut QueryLens<'w, Q, F>) -> Query<'s, 's, Q, F>

Converts to this type from the input type.
Source§

impl<'w, 's, D, F> IntoIterator for Query<'w, 's, D, F>

Source§

type Item = <D as QueryData>::Item<'w, 's>

The type of the elements being iterated over.
Source§

type IntoIter = QueryIter<'w, 's, D, F>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <Query<'w, 's, D, F> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'w, 's, D, F> IntoIterator for &'w Query<'_, 's, D, F>
where D: QueryData, F: QueryFilter,

Source§

type Item = <<D as QueryData>::ReadOnly as QueryData>::Item<'w, 's>

The type of the elements being iterated over.
Source§

type IntoIter = QueryIter<'w, 's, <D as QueryData>::ReadOnly, F>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'w Query<'_, 's, D, F> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'w, 's, D, F> IntoIterator for &'w mut Query<'_, 's, D, F>

Source§

type Item = <D as QueryData>::Item<'w, 's>

The type of the elements being iterated over.
Source§

type IntoIter = QueryIter<'w, 's, D, F>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'w mut Query<'_, 's, D, F> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'w, 's, D, F> ReadOnlySystemParam for Query<'w, 's, D, F>
where D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static,

Source§

impl<D, F> SystemParam for Query<'_, '_, D, F>
where D: QueryData + 'static, F: QueryFilter + 'static,

Source§

type State = QueryState<D, F>

Used to store data which persists across invocations of a system.
Source§

type Item<'w, 's> = Query<'w, 's, D, F>

The item type returned when constructing this system param. The value of this associated type should be Self, instantiated with new lifetimes. Read more
Source§

fn init_state(world: &mut World) -> <Query<'_, '_, D, F> as SystemParam>::State

Creates a new instance of this param’s State.
Source§

fn init_access( state: &<Query<'_, '_, D, F> as SystemParam>::State, system_meta: &mut SystemMeta, system_access: &mut SystemAccess, world: &mut World, )

Registers any World access used by this SystemParam. Read more
Source§

unsafe fn get_param<'w, 's>( state: &'s mut <Query<'_, '_, D, F> as SystemParam>::State, system_meta: &SystemMeta, world: UnsafeWorldCell<'w>, change_tick: Tick, ) -> Result<<Query<'_, '_, D, F> as SystemParam>::Item<'w, 's>, SystemParamValidationError>

Creates a parameter to be passed into a SystemParamFunction. Read more
Source§

fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World)

Applies any deferred mutations stored in this SystemParam’s state. This is used to apply Commands during ApplyDeferred.
Source§

fn queue( state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld<'_>, )

Queues any deferred mutations to be applied at the next ApplyDeferred.
Source§

impl<'w, 's, D, F> SystemParamBuilder<Query<'w, 's, D, F>> for QueryState<D, F>
where D: QueryData + 'static, F: QueryFilter + 'static,

Source§

fn build(self, world: &mut World) -> QueryState<D, F>

Registers any World access used by this SystemParam and creates a new instance of this param’s State.
Source§

fn build_state(self, world: &mut World) -> SystemState<P>

Create a SystemState from a SystemParamBuilder. To create a system, call SystemState::build_system on the result.
Source§

fn build_system<Marker, In, Out, Func>( self, func: Func, ) -> IntoBuilderSystem<Marker, In, Out, Func, Self>
where Self: 'static, Func: SystemParamFunction<Marker, Param = P>,

Create a System from a SystemParamBuilder directly. Read more
Source§

impl<'w, 's, D, F, T> SystemParamBuilder<Query<'w, 's, D, F>> for QueryParamBuilder<T>
where D: QueryData + 'static, F: QueryFilter + 'static, T: FnOnce(&mut QueryBuilder<'_, D, F>),

Source§

fn build(self, world: &mut World) -> QueryState<D, F>

Registers any World access used by this SystemParam and creates a new instance of this param’s State.
Source§

fn build_state(self, world: &mut World) -> SystemState<P>

Create a SystemState from a SystemParamBuilder. To create a system, call SystemState::build_system on the result.
Source§

fn build_system<Marker, In, Out, Func>( self, func: Func, ) -> IntoBuilderSystem<Marker, In, Out, Func, Self>
where Self: 'static, Func: SystemParamFunction<Marker, Param = P>,

Create a System from a SystemParamBuilder directly. Read more

Auto Trait Implementations§

§

impl<'world, 'state, D, F = ()> !RefUnwindSafe for Query<'world, 'state, D, F>

§

impl<'world, 'state, D, F = ()> !UnwindSafe for Query<'world, 'state, D, F>

§

impl<'world, 'state, D, F> Freeze for Query<'world, 'state, D, F>
where &'state QueryState<D, F>: Freeze,

§

impl<'world, 'state, D, F> Send for Query<'world, 'state, D, F>
where &'state QueryState<D, F>: Send,

§

impl<'world, 'state, D, F> Sync for Query<'world, 'state, D, F>
where &'state QueryState<D, F>: Sync,

§

impl<'world, 'state, D, F> Unpin for Query<'world, 'state, D, F>
where &'state QueryState<D, F>: Unpin,

§

impl<'world, 'state, D, F> UnsafeUnpin for Query<'world, 'state, D, F>
where &'state QueryState<D, F>: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> EntitySet for T

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> HitDataExtra for T
where T: Send + Sync + Debug + Any + 'static,

Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> InitializeFromFunction<T> for T

Source§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T> PatchTemplate for T
where T: Template,

Source§

fn patch_template<F>(func: F) -> TemplatePatch<F, T>
where F: FnOnce(&mut T, &mut ResolveContext<'_>),

Takes a “patch function” func that patches this Template, and turns it into a TemplatePatch.
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

Source§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
Source§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

Source§

fn super_from(input: T) -> O

Convert from a type to another type.
Source§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

Source§

fn super_into(self) -> O

Convert from a type to another type.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> Template for T
where T: Clone + Unpin,

Source§

type Output = T

The type of value produced by this Template.
Source§

fn build_template( &self, _context: &mut TemplateContext<'_, '_>, ) -> Result<<T as Template>::Output, BevyError>

Uses this template and the given entity context to produce a Template::Output.
Source§

fn clone_template(&self) -> T

Clones this template. See Clone.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of self.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more