The behavior of Query seems to have some issues under concurrent conditions. #12555
-
I try the following code: use bevy::app::{App, FixedUpdate, Startup};
use bevy::prelude::*;
#[derive(Component)]
struct Actor;
#[derive(Component)]
struct Attack;
#[derive(Component)]
struct AttackRestrain;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(FixedUpdate, (give, get))
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Actor);
}
fn give(query: Query<(Entity, Option<&AttackRestrain>), With<Actor>>, mut commands: Commands) {
for (entity, attack_restrain) in query.iter() {
println!("a");
if let None = attack_restrain {
println!("b");
commands.entity(entity).insert(Attack);
}
println!("c");
}
}
fn get(query: Query<Entity, (With<Actor>, With<Attack>)>, mut commands: Commands) {
for entity in query.iter() {
println!("1");
commands.entity(entity).insert(AttackRestrain).remove::<Attack>();
println!("2");
}
} As you can see, there is not
But if On the other hand, if there is a I'm wondering if my understanding of the ECS is not thorough enough. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
From what I can see this is what happens:
Overall I think the behaviour is expected, just not intuitive. Both systems and commands can run in any order, and systems are not guaranteed to see the result of commands of other systems unless they are relatively ordered (as you noticed when you put a |
Beta Was this translation helpful? Give feedback.
From what I can see this is what happens:
AttackRestraint
, sogive
enqueues a command to addAttack
to itAttack
(yet), soget
doesn't do anythinga b c
is printedAttack
is then added by the enqueued commandAttackRestraint
, sogive
enqueues a command to addAttack
to it (again)Attack
, soget
enqueues a command to addAttackRestraint
and removeAttack
1 2 a b c
is printedget
's command runs first andget
runs second, with the result thatAttackRestraint
is added,Attack
is removed, and thenAttack
is re-…