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, sogiveenqueues a command to addAttackto itAttack(yet), sogetdoesn't do anythinga b cis printedAttackis then added by the enqueued commandAttackRestraint, sogiveenqueues a command to addAttackto it (again)Attack, sogetenqueues a command to addAttackRestraintand removeAttack1 2 a b cis printedget's command runs first andgetruns second, with the result thatAttackRestraintis added,Attackis removed, and thenAttackis re-…