State+Scene Transititions

This commit is contained in:
2025-07-05 16:04:43 -04:00
parent a62002ee8b
commit bc0ef5fbfa
14 changed files with 145 additions and 66 deletions

View File

@@ -2,15 +2,14 @@
macro_rules! configure_sets {
(
$app: expr,
$system_set: expr,
$condition: expr
) => {
$app.configure_sets(PreUpdate, $system_set.run_if($condition))
.configure_sets(Update, $system_set.run_if($condition))
.configure_sets(PostUpdate, $system_set.run_if($condition))
.configure_sets(Last, $system_set.run_if($condition));
$app.configure_sets(FixedPreUpdate, $system_set.run_if($condition))
.configure_sets(FixedUpdate, $system_set.run_if($condition))
.configure_sets(FixedPostUpdate, $system_set.run_if($condition));
$app.configure_sets(PreUpdate, $condition)
.configure_sets(Update, $condition)
.configure_sets(PostUpdate, $condition)
.configure_sets(Last, $condition);
$app.configure_sets(FixedPreUpdate, $condition)
.configure_sets(FixedUpdate, $condition)
.configure_sets(FixedPostUpdate, $condition);
};
}

View File

@@ -2,16 +2,16 @@ use bevy::prelude::*;
#[cfg(feature = "dev")]
use bevy::window::PrimaryWindow;
use crate::components::camera::*;
use crate::{components::camera::*, states::play::PlaySystems};
pub struct CameraPlugin;
impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, camera_pitch);
app.add_systems(Update, camera_attachment);
app.add_systems(Update, camera_pitch.in_set(PlaySystems));
app.add_systems(Update, camera_attachment.in_set(PlaySystems));
#[cfg(feature = "dev")]
app.add_systems(Update, camera_toggle);
app.add_systems(Update, camera_toggle.in_set(PlaySystems));
}
}

View File

@@ -1,12 +1,15 @@
use bevy::prelude::*;
use crate::components::camera::{FollowCam, FollowTarget};
use crate::{
components::camera::{FollowCam, FollowTarget},
states::play::PlaySystems,
};
pub struct FollowCamPlugin;
impl Plugin for FollowCamPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, (set_cam_target, follow_cam).chain());
app.add_systems(Update, (set_cam_target, follow_cam).chain().in_set(PlaySystems));
}
}

View File

@@ -8,8 +8,8 @@ use crate::{
states::{
game::*,
input::{InputState, PlayerState},
loading::{AssetLoadingState, StartupLoadingState},
menu::MenuState,
play::PlayStartupSystems,
},
};
use bevy::{
@@ -24,22 +24,11 @@ pub struct GamePlugin;
impl Plugin for GamePlugin {
fn build(&self, app: &mut bevy::app::App) {
app.init_state::<AssetLoadingState>();
app.init_state::<StartupLoadingState>();
app.insert_state(GameState::Startup);
app.init_state::<MenuState>();
app.init_state::<PlayerState>();
app.add_loading_state(
LoadingState::new(AssetLoadingState::Loading).continue_to_state(AssetLoadingState::Finalizing),
)
.add_loading_state(
LoadingState::new(StartupLoadingState::Loading).continue_to_state(StartupLoadingState::Finalizing),
);
app.add_plugins((
FollowCamPlugin,
CameraPlugin,
StateManagementPlugin,
MainMenuPlugin,
// ShipPlugin,
TypesPlugin,
PlayerPlugin,
@@ -49,7 +38,7 @@ impl Plugin for GamePlugin {
#[cfg(feature = "dev-phys")]
RapierDebugRenderPlugin::default(),
));
app.add_systems(Startup, (setup_scene, spawn_ship).chain());
app.add_systems(Update, (setup_scene, spawn_ship).chain().in_set(PlayStartupSystems));
}
}

38
src/plugins/main_menu.rs Normal file
View File

@@ -0,0 +1,38 @@
use bevy::prelude::*;
use crate::states::{
game::GameState,
menu::{MainMenuSystems, MenuCleanupSystems, MenuStartupSystems, MenuState},
play::PlayState,
};
pub struct MainMenuPlugin;
impl Plugin for MainMenuPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, spawn_menu.in_set(MenuStartupSystems));
app.add_systems(Update, clean_menu.in_set(MenuCleanupSystems));
app.add_systems(Update, main_menu.in_set(MainMenuSystems));
}
}
fn spawn_menu(mut next: ResMut<NextState<MenuState>>) {
next.set(MenuState::Main);
info_once!("Moving to MenuState:{:?}", MenuState::Main);
}
fn clean_menu(mut next: ResMut<NextState<MenuState>>) {
next.set(MenuState::Idle);
info_once!("Moving to MenuState:{:?}", MenuState::Loading);
}
fn main_menu(
mut next_menu: ResMut<NextState<MenuState>>,
mut next_game: ResMut<NextState<GameState>>,
mut next_play_state: ResMut<NextState<PlayState>>,
) {
next_menu.set(MenuState::Cleanup);
next_game.set(GameState::InGame);
next_play_state.set(PlayState::Loading);
info_once!("Moving to InGame");
}

View File

@@ -2,6 +2,7 @@
mod camera;
mod follow_cam;
mod game;
mod main_menu;
mod player;
mod ship;
mod ship_cam;
@@ -12,6 +13,7 @@ mod types;
pub use camera::*;
pub use follow_cam::*;
pub use game::*;
pub use main_menu::*;
pub use player::*;
pub use ship::*;
pub use ship_cam::*;

View File

@@ -9,7 +9,7 @@ use crate::{
player::{GravityDirection, JumpSpeed, MoveSpeed, PlayerDrag, PlayerForce, PlayerMotion, PlayerVelocity},
tags::Player,
},
states::input::PlayerInputSystems,
states::{input::PlayerInputSystems, play::PlaySystems},
utils::{input::get_mouse_delta, rotation::get_alignment_rotation_preserve_twist},
};
@@ -18,8 +18,13 @@ pub struct PlayerPlugin;
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, (keyboard_input, player_look).in_set(PlayerInputSystems));
app.add_systems(Update, (apply_gravity, apply_forces, apply_motion, apply_drag).chain());
app.add_systems(Update, align_with_gravity);
app.add_systems(
Update,
(apply_gravity, apply_forces, apply_motion, apply_drag)
.chain()
.in_set(PlaySystems),
);
app.add_systems(Update, align_with_gravity.in_set(PlaySystems));
}
}

View File

@@ -1,15 +1,15 @@
use bevy::{input::mouse::MouseMotion, prelude::*};
use bevy_rapier3d::prelude::*;
use crate::{components::tags::Ship, utils::input::get_mouse_delta};
use crate::{components::tags::Ship, states::play::PlaySystems, utils::input::get_mouse_delta};
pub struct ShipPlugin;
impl Plugin for ShipPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, ship_controls);
app.add_systems(Update, ship_controls.in_set(PlaySystems));
#[cfg(feature = "dev-viz")]
app.add_systems(Update, ship_debug);
app.add_systems(Update, ship_debug.in_set(PlaySystems));
}
}

View File

@@ -1,8 +1,10 @@
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
use crate::{
configure_sets,
states::{
game::{GameState, InGameSystems, MenuSystems},
input::{InputState, PlayerInputSystems, PlayerState},
menu::{
MainMenuSystems, MenuCleanupSystems, MenuStartupSystems, MenuState, OptionsMenuSystems, SavesMenuSystems,
@@ -17,25 +19,76 @@ impl Plugin for StateManagementPlugin {
fn build(&self, app: &mut App) {
app.init_state::<PlayerState>();
app.init_state::<InputState>();
app.init_state::<GameState>();
app.init_state::<MenuState>();
app.init_state::<PlayState>();
//Loading
app.add_loading_state(LoadingState::new(MenuState::Loading).continue_to_state(MenuState::Startup))
.add_loading_state(LoadingState::new(PlayState::Loading).continue_to_state(PlayState::Startup));
//Game
configure_sets!(app, MenuSystems.run_if(in_state(GameState::MainMenu)));
configure_sets!(app, InGameSystems.run_if(in_state(GameState::InGame)));
//Menu
configure_sets!(app, MenuStartupSystems, in_state(MenuState::Startup));
configure_sets!(app, MainMenuSystems, in_state(MenuState::Main));
configure_sets!(app, OptionsMenuSystems, in_state(MenuState::Options));
configure_sets!(app, SavesMenuSystems, in_state(MenuState::Saves));
configure_sets!(app, MenuCleanupSystems, in_state(MenuState::Cleanup));
configure_sets!(
app,
MenuStartupSystems
.run_if(in_state(MenuState::Startup))
.in_set(MenuSystems)
);
configure_sets!(
app,
MainMenuSystems.run_if(in_state(MenuState::Main)).in_set(MenuSystems)
);
configure_sets!(
app,
OptionsMenuSystems
.run_if(in_state(MenuState::Options))
.in_set(MenuSystems)
);
configure_sets!(
app,
SavesMenuSystems.run_if(in_state(MenuState::Saves)).in_set(MenuSystems)
);
configure_sets!(app, MenuCleanupSystems.run_if(in_state(MenuState::Cleanup)));
//Play
configure_sets!(app, PlayStartupSystems, in_state(PlayState::Startup));
configure_sets!(app, PausedSystems, in_state(PlayState::Paused));
configure_sets!(app, PlaySystems, in_state(PlayState::Playing));
configure_sets!(app, PlayCleanupSystems, in_state(PlayState::Cleanup));
configure_sets!(
app,
PlayStartupSystems
.run_if(in_state(PlayState::Startup))
.in_set(InGameSystems)
);
configure_sets!(
app,
PausedSystems.run_if(in_state(PlayState::Paused)).in_set(InGameSystems)
);
configure_sets!(
app,
PlaySystems.run_if(in_state(PlayState::Playing)).in_set(InGameSystems)
);
configure_sets!(app, PlayCleanupSystems.run_if(in_state(PlayState::Cleanup)));
//Input
configure_sets!(
app,
PlayerInputSystems,
in_state(InputState::World).and(in_state(PlayState::Playing))
PlayerInputSystems
.run_if(in_state(InputState::World))
.in_set(PlaySystems)
);
//State Transitions
app.add_systems(Update, game_startup.in_set(PlayStartupSystems));
app.add_systems(Update, game_cleanup.in_set(PlayCleanupSystems));
}
}
fn game_startup(mut next: ResMut<NextState<PlayState>>) {
next.set(PlayState::Playing);
}
fn game_cleanup(mut next: ResMut<NextState<PlayState>>) {
next.set(PlayState::Idle);
}

View File

@@ -3,7 +3,12 @@ use bevy::prelude::*;
#[derive(States, Debug, Reflect, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GameState {
#[default]
Startup,
MainMenu,
PlayGame,
InGame,
}
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct MenuSystems;
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct InGameSystems;

View File

@@ -1,18 +0,0 @@
use bevy::prelude::*;
#[derive(States, Debug, Default, Clone, PartialEq, Eq, Hash)]
pub enum StartupLoadingState {
#[default]
Pending,
Loading,
Finalizing,
Done,
}
#[derive(States, Debug, Default, Clone, PartialEq, Eq, Hash)]
pub enum AssetLoadingState {
#[default]
Pending,
Loading,
Finalizing,
Done,
}

View File

@@ -3,7 +3,9 @@ use bevy::prelude::*;
#[derive(States, Debug, Reflect, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MenuState {
#[default]
Idle,
Loading,
AssetFinalize,
Startup,
Main,
Saves,

View File

@@ -1,5 +1,4 @@
pub mod game;
pub mod input;
pub mod loading;
pub mod menu;
pub mod play;

View File

@@ -2,8 +2,10 @@ use bevy::prelude::*;
#[derive(States, Debug, Reflect, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PlayState {
Idle,
#[default]
Loading,
AssetFinalize,
Startup,
Playing,
Paused,