You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/learn/book/storing-data/queries.md
+348-6Lines changed: 348 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,10 +6,352 @@ weight = 4
6
6
status = 'hidden'
7
7
+++
8
8
9
-
Queries let you pull data from the world.
9
+
Queries are your primary tool for interacting with the Bevy world,
10
+
allowing you to efficiently read and write component data from entities.
11
+
Queries create a filtered "view" into the metaphorical database that makes up our ECS.
12
+
With that view, you can iterate over the requested components, ask what the "row number" (`Entity`) is for each element,
13
+
or fetch the matching components for a particular `Entity` value.
10
14
11
-
- Query::iter
12
-
- Query::single
13
-
- Query::get
14
-
- Multiple items in queries
15
-
- Query filters
15
+
We introduced queries briefly in our [introduction](../intro/) to Bevy: if you're brand to new Bevy or ECS, start there.
16
+
17
+
## Anatomy of a query
18
+
19
+
To understand how queries work in a bit more detail, let's take a look at the anatomy of a [`Query`].
20
+
The [`Query<D, F>`] type has two [generic type parameters]: `D`, which must implement the [`QueryData`] trait,
21
+
and `F`, which must implement the [`QueryFilter`] trait.
22
+
23
+
`D` describes "which data should I access", while `F` describes "how should I restrict the returned entities".
24
+
Only entities which match *all* of the terms in `D`*and*`F` will be included in your query.
25
+
26
+
When we write `Query<&Life, With<Player>>`, we're supplying these generics, setting `D` to `&Life` and `F` to `With<Player>`,
27
+
separated by a comma.
28
+
Bevy uses the information in the [`QueryData`] and [`QueryFilter`] traits,
29
+
along with the [`WorldQuery`] supertrait, to look up components of
30
+
the correct type in the world and supply them to your system via [dependency injection].
31
+
32
+
If we don't want to fetch any data, or perform any filtering,
33
+
we can use `()`, Rust's ["unit type"] in place of `D` or `F`.
34
+
35
+
Inside the `Query` type, the `F: QueryFilter` generic defaults to `()`, allowing us to avoid explicitly writing `Query<&Life, ()>` when we don't want to filter. This simplified, filter-less form of query looks like `Query<&Life>`, which will fetch all instances of the `Life` component in the world.
36
+
37
+
To access more than one component at once, or add multiple filters at the same time,
38
+
we can combine [`QueryData`] or [`QueryFilter`] types by putting them inside of a [tuple],
39
+
wrapping them with parentheses.
40
+
41
+
[generic type parameters]: (https://doc.rust-lang.org/book/ch10-01-syntax.html)
Sometimes, you want to swap from the default "and" logic, where all of the components must be present, to "or" logic, where any of the components can be present. To do so, you can use `Option` and a few special types:
102
+
103
+
-`Query<Option<&Life>>`, for an [`Option`] that contains the component value if present and nothing if it is absent
104
+
-`Query<AnyOf<(&Life, &Mana)>>` which acts as a wrapper for multiple `Option``QueryData` types
105
+
-`Query<Has<Life>>`, which contains `true` if the component is present, and `false` if the component is absent
106
+
-`Query<(), Or<(With<Life>, With<Mana>)>>`, which combines query filters via an `Or` relationship
107
+
- Using `()` in the `QueryData` field means that no data will be fetched: the only information retrieved is whether or not the query contains a given entity.
108
+
109
+
As you can see, Bevy's type-driven querying can be quite expressive and elaborate!
110
+
Don't worry, though: most of your queries will be quite simple, requesting a few pieces of data with a simple filter.
Simply reading the values of our components isn't very useful: in order to actually implement gameplay,
117
+
we need to change those values!
118
+
119
+
We can change whether we're requesting the data "immutably" (read-only) or "mutably" (read-write) by changing `Query<&Life>` to `Query<&mut Life>` (pronounced "ref Life" and "ref mute Life", respectively).
120
+
The ampersand is Rust's read-only [reference] indicator,
121
+
while `&mut` is for mutable references, making it easy to remember the syntax once you're familiar with Rust.
122
+
123
+
Let's take a look at how that might look in practice:
0 commit comments