rustbevy

How to fix Bevy ECS queries conflicting even with filters


I am trying to execute the below two queries in a bevy system function.

fn move_player(
    mut player_query: Query<(&mut Velocity, &mut Transform, &SpriteSize, &Player), With<PlayerId>>,
    wall_query: Query<(&Transform, &SpriteSize), With<Barrier>>,
) {
    for (mut player_velocity, mut player_tf, player_size, player) in player_query.iter_mut() {
        for (wall_tf, wall_size) in wall_query.iter() {
        }
    }
}

I inserted the PlayerId component to the Player entity and the Barrier component to the Wall entities when spawning them. The PlayerId is not inserted in Wall entities and the Barrier component is not inserted in the Player entity.

When I run the above function I get the error below;

thread 'main' panicked at 'error[B0001]: Query<(&mut bevy_transform::components::transform::Transform, &bevy_fantasy::Sprite Size), bevy_ecs::query::filter::With<bevy_fantasy::Barrier>> in system bevy_fantasy::player::move_player accesses component( s) bevy_transform::components::transform::Transform in a way that conflicts with a previous system parameter. Consider using Without<T> to create disjoint Queries or merging conflicting Queries into a ParamSet.

Why are the 2 queries conflicting when I filter them using unique components?


Solution

  • You're using

    mut player_query: Query<(&mut Velocity, &mut Transform, &SpriteSize, &Player), With<PlayerId>>,
    wall_query: Query<(&Transform, &SpriteSize), With<Barrier>>,
    

    All entities that have Transform, Velocity, SpriteSize, Player, PlayerId, and Barrier components are in both queries. There is no way for Rust or Bevy to tell that there aren't any such Entities.

    Getting mutable references to Transform would therefore be undefined behaviour because it violates the aliasing rules of mutable references.

    To fix it just follow one of the suggestions.