Tainted\\Coders

Manage app state

Bevy version: 0.17Last updated:

Derive a States type in an AppState enum:

#[derive(Debug, Clone, Eq, PartialEq, Hash, Default, States)]
enum AppState {
  #[default]
  MainMenu,
  InGame,
  Paused,
}

impl AppState {
  fn next(&self) -> Self {
    match *self {
      AppState::MainMenu => AppState::InGame,
      AppState::InGame => AppState::Paused,
      AppState::Paused => AppState::InGame,
    }
  }
}

Using the NextState resource you can transition the apps state between the enum values, either directly or using the transitions we implemented:

fn start_game(mut next_state: ResMut<NextState<AppState>>) {
  next_state.set(AppState::InGame);
}

fn toggle_game_pause(
  mut next_state: ResMut<NextState<AppState>>,
  current_state: Res<State<AppState>>,
  input: Res<ButtonInput<KeyCode>>,
) {
  if input.just_pressed(KeyCode::Escape) {
    next_state.set(current_state.next());
  }
}

You can then use the state of your app to run systems conditionally:

fn main() {
  App::new()
    .add_plugins(DefaultPlugins)
    // Add our state to our app definition
    .init_state::<AppState>()
    // We can add systems to trigger during transitions
    .add_systems(OnEnter(AppState::MainMenu), spawn_menu)
    .add_systems(OnExit(AppState::MainMenu), despawn_menu)
    // Or we can use run conditions
    .add_systems(Update, play_game.run_if(in_state(AppState::InGame)))
    .add_systems(Update, toggle_game_pause)
    .run();

}