bevyengine / bevyengine/bevy

using iter_descendants, query filter should apply to returned values, but not limit the walk

Open
#18,686 1 comment 0 reactions 0 assignees View on GitHub
A-ECS C-Feature D-Complex S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

16.0-rc.3

## What you did

```rust
use bevy::prelude::*;

#[derive(Component)]
struct TreeTrunk;
#[derive(Component)]
struct TreeBranch;
#[derive(Component)]
struct Leaf;

fn spawn_tree(mut commands: Commands) {
commands
.spawn(TreeTrunk)
.with_child(TreeBranch)
.with_child(Leaf);
}

fn find_leaves(
trunk_query: Single>,
leaves_query: Query<&Children, With>,
any_children_query: Query<&Children>,
) {
let trunk = trunk_query.into_inner();
for _leaf in leaves_query.iter_descendants(trunk) {
info!("found leaf!");
}
for _item in any_children_query.iter_descendants(trunk) {
info!("found descendant!");
}
}

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, spawn_tree)
.add_systems(Update, find_leaves)
.run();
}

```

## What went wrong

When I run this, I get a bunch of logging output saying "found descendant!"

What I would like to have happen is that I get "found leaf!" as well as "found descendant!"

## Additional information

The `iter_descendants` iterator applies the query including its filter on every step of iterating through decendants. This makes the query's filter not very useful when you are interested in grandchild entities (or great-, great-great- etc.), because you'd need to have the filter match all the intermediate child entities in addition to the grandchildren that you want to match.

It would be more useful if `iter_descendants` walked all the descendants, then applied the filter only to the entities it's returning to the caller.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.