Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/errors/B0001.md
6586 views

B0001

To keep Rust rules on references (either one mutable reference or any number of immutable references) on a component, it is not possible to have two queries on the same component when one requests mutable access to it in the same system.

Erroneous code example:

use bevy::prelude::*; #[derive(Component)] struct Player; #[derive(Component)] struct Enemy; fn move_enemies_to_player( mut enemies: Query<&mut Transform, With<Enemy>>, player: Query<&Transform, With<Player>>, ) { // ... } fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Update, move_enemies_to_player) .run(); }

This will panic, as it's not possible to have both a mutable and an immutable query on Transform at the same time.

You have two solutions:

Solution #1: use disjoint queries using Without

As a Player entity won't be an Enemy at the same time, those two queries will actually never target the same entity. This can be encoded in the query filter with Without:

use bevy::prelude::*; #[derive(Component)] struct Player; #[derive(Component)] struct Enemy; fn move_enemies_to_player( mut enemies: Query<&mut Transform, With<Enemy>>, player: Query<&Transform, (With<Player>, Without<Enemy>)>, ) { // ... } fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Update, move_enemies_to_player) .run(); }

Solution #2: use a ParamSet

A ParamSet will let you have conflicting queries as a parameter, but you will still be responsible for not using them at the same time in your system.

use bevy::prelude::*; #[derive(Component)] struct Player; #[derive(Component)] struct Enemy; fn move_enemies_to_player( mut transforms: ParamSet<( Query<&mut Transform, With<Enemy>>, Query<&Transform, With<Player>>, )>, ) { // ... } fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Update, move_enemies_to_player) .run(); }