Confused about state propagation #13847
-
Lets consider the following simple program, where #[derive(Event, Default)]
pub struct ExitApp;
#[derive(States, Debug, Hash, Eq, PartialEq, Clone, Copy, Default)]
pub enum AppState {
#[default]
Running,
Exit,
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.init_state::<AppState>()
.add_event::<ExitApp>()
.add_systems(
Update,
system_one.run_if(in_state(AppState::Running)),
)
.add_systems(Update, system_two)
.run();
}
fn system_one(mut counter: Local<u32>, mut event_writer: EventWriter<ExitApp>) {
println!("system_one:");
if *counter == 3 {
println!(" Sending exit event");
event_writer.send_default();
} else {
println!(" Incrementing local counter");
*counter += 1;
}
println!();
}
fn system_two(mut app_state: ResMut<NextState<AppState>>, mut event_reader: EventReader<ExitApp>) {
for _ in event_reader.read() {
app_state.set(AppState::Exit);
}
} I get the following output when running above program:
As one can see, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
System two is running before system one (at least some of the time!). States are by default only processed once per frame before update, so you're writing, reading, queuing a transition, writing again and then finally transitioning on the next frame. If you add system ordering to ensure that system two always runs after this should go away. |
Beta Was this translation helpful? Give feedback.
System two is running before system one (at least some of the time!). States are by default only processed once per frame before update, so you're writing, reading, queuing a transition, writing again and then finally transitioning on the next frame.
If you add system ordering to ensure that system two always runs after this should go away.