-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Open
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsA-StatesApp-level states machinesApp-level states machinesC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorS-Needs-InvestigationThis issue requires detective work to figure out what's going wrongThis issue requires detective work to figure out what's going wrong
Description
Bevy version
0.15.3
What you did
use bevy::prelude::*;
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
pub enum Phases {
#[default]
None,
Phase1,
Phase2,
}
#[derive(Event, Debug, Default)]
pub struct AnEvent;
#[derive(Resource, Debug)]
struct ChangeDirectionTimer {
timer: Timer,
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_state::<Phases>()
.add_event::<AnEvent>()
.insert_resource(ChangeDirectionTimer {
timer: Timer::from_seconds(1., TimerMode::Once),
})
.add_systems(Startup, start)
.add_systems(OnEnter(Phases::Phase1), send_event1)
.add_systems(Update, end_phase1
.run_if(in_state(Phases::Phase1).and(on_event::<AnEvent>)))
.add_systems(OnEnter(Phases::Phase2), send_event2)
.add_systems(Update, end_phase2
.run_if(in_state(Phases::Phase2).and(on_event::<AnEvent>)))
.run();
}
fn start(mut next_state: ResMut<NextState<Phases>>) {
next_state.set(Phases::Phase1);
}
fn send_event1(
mut event: EventWriter<AnEvent>,
) {
println!("Sending event 1");
event.send_default();
}
fn end_phase1(
mut event: EventReader<AnEvent>,
mut next_state: ResMut<NextState<Phases>>,
) {
for _ in event.read() {
println!("Ending phase 1");
next_state.set(Phases::Phase2);
}
}
fn send_event2(
mut event: EventWriter<AnEvent>,
time: Res<Time>,
mut timer: ResMut<ChangeDirectionTimer>,
) {
timer.timer.tick(time.delta());
if timer.timer.just_finished() {
println!("Sending event 2");
event.send_default();
}
}
fn end_phase2(
mut event: EventReader<AnEvent>,
mut next_state: ResMut<NextState<Phases>>,
) {
for _ in event.read() {
println!("Ending phase 2");
next_state.set(Phases::None);
}
}
What went wrong
The output of this code is:
Sending event 1
Ending phase 1
Ending phase 2
As the system end_phase2
only runs in the Phase2
state, it should be triggered by the delayed event 2, but it's like it is triggered still by the first event.
This is confirmed by commenting out the if
statement in send_event2
, which results in:
Sending event 1
Ending phase 1
Sending event 2
Ending phase 2
Ending phase 2
So end_phase2
is actually triggered twice despite the first event is triggered in another state with respect to the one during which end_phase2
should be running.
Additional information
Am I missing something or is it a bug?
Thanks!
Metadata
Metadata
Assignees
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsA-StatesApp-level states machinesApp-level states machinesC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorS-Needs-InvestigationThis issue requires detective work to figure out what's going wrongThis issue requires detective work to figure out what's going wrong