From 91acda47412b007e0f373e0f85054a0f1f9169da Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 15:03:11 +0200 Subject: [PATCH 1/7] Update fast builds to current Bevy recommendation --- .cargo/config_fast_builds.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cargo/config_fast_builds.toml b/.cargo/config_fast_builds.toml index a1323406..b57e5dc6 100644 --- a/.cargo/config_fast_builds.toml +++ b/.cargo/config_fast_builds.toml @@ -1,4 +1,4 @@ -# Rename this file to `config.toml` to enable "fast build" configuration. Please read the notes below. +# Add the contents of this file to `config.toml` to enable "fast build" configuration. Please read the notes below. # NOTE: For maximum performance, build using a nightly compiler # If you are using rust stable, remove the "-Zshare-generics=y" below. @@ -30,7 +30,7 @@ rustflags = [ [target.x86_64-pc-windows-msvc] linker = "rust-lld.exe" # Use LLD Linker rustflags = [ - "-Zshare-generics=n", # (Nightly) + "-Zshare-generics=n", "-Zthreads=0", # (Nightly) Use improved multithreading with the recommended amount of threads. ] From e276c80dc94f832518cf7c5cc2f6f22dc4cd9c02 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 15:21:00 +0200 Subject: [PATCH 2/7] Refactor system sets --- src/level_instantiation/on_spawn/hidden.rs | 9 +--- src/lib.rs | 4 ++ src/movement/character_controller.rs | 8 +-- src/movement/character_controller/models.rs | 6 +-- src/movement/navigation.rs | 6 +-- src/particles.rs | 5 +- src/player_control/camera.rs | 18 ++----- src/player_control/camera/rig/arm.rs | 7 ++- src/player_control/player_embodiment.rs | 8 ++- src/system_set.rs | 58 +++++++++++++++++++++ src/util.rs | 6 --- src/world_interaction/dialog.rs | 6 +-- src/world_interaction/interaction_ui.rs | 11 ++-- 13 files changed, 90 insertions(+), 62 deletions(-) create mode 100644 src/system_set.rs diff --git a/src/level_instantiation/on_spawn/hidden.rs b/src/level_instantiation/on_spawn/hidden.rs index bf8b2eee..1df88a40 100644 --- a/src/level_instantiation/on_spawn/hidden.rs +++ b/src/level_instantiation/on_spawn/hidden.rs @@ -1,6 +1,5 @@ use crate::GameState; use bevy::prelude::*; -use bevy_xpbd_3d::PhysicsSet; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Eq, PartialEq, Component, Reflect, Serialize, Deserialize, Default)] @@ -8,12 +7,8 @@ use serde::{Deserialize, Serialize}; struct Hidden; pub(super) fn plugin(app: &mut App) { - app.register_type::().add_systems( - Update, - spawn - .after(PhysicsSet::Sync) - .run_if(in_state(GameState::Playing)), - ); + app.register_type::() + .add_systems(Update, spawn.run_if(in_state(GameState::Playing))); } fn spawn(hidden: Query>, mut commands: Commands) { diff --git a/src/lib.rs b/src/lib.rs index 06b70d94..463bb557 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,9 +22,12 @@ pub(crate) mod movement; pub(crate) mod particles; mod player_control; mod shader; +mod system_set; pub(crate) mod util; mod world_interaction; +pub(crate) use system_set::GameSystemSet; + #[derive(States, Default, Clone, Eq, PartialEq, Debug, Hash)] enum GameState { /// During the loading State the loading_plugin will load our assets @@ -55,6 +58,7 @@ pub struct GamePlugin; impl Plugin for GamePlugin { fn build(&self, app: &mut App) { app.init_state::().add_plugins(( + system_set::plugin, bevy_config::plugin, menu::plugin, movement::plugin, diff --git a/src/movement/character_controller.rs b/src/movement/character_controller.rs index c74d86e1..5805a72a 100644 --- a/src/movement/character_controller.rs +++ b/src/movement/character_controller.rs @@ -1,9 +1,9 @@ +use crate::system_set::GameSystemSet; use crate::GameState; pub(crate) use animation::AnimationState; use bevy::prelude::*; use bevy_tnua::prelude::*; use bevy_tnua_xpbd3d::*; -use bevy_xpbd_3d::PhysicsSet; pub(crate) use components::*; mod animation; @@ -19,15 +19,11 @@ pub(super) fn plugin(app: &mut App) { Update, (apply_jumping, apply_walking) .chain() - .in_set(GeneralMovementSystemSet) - .before(PhysicsSet::Prepare) + .in_set(GameSystemSet::GeneralMovement) .run_if(in_state(GameState::Playing)), ); } -#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] -pub(crate) struct GeneralMovementSystemSet; - fn apply_walking( mut character_query: Query<( &mut TnuaController, diff --git a/src/movement/character_controller/models.rs b/src/movement/character_controller/models.rs index ed65cc6b..6f26f446 100644 --- a/src/movement/character_controller/models.rs +++ b/src/movement/character_controller/models.rs @@ -1,6 +1,5 @@ use crate::movement::character_controller::FloatHeight; use crate::GameState; -use bevy::transform::TransformSystem; use bevy::{prelude::*, render::view::NoFrustumCulling}; use bevy_tnua::controller::TnuaController; use bevy_xpbd_3d::prelude::*; @@ -8,10 +7,7 @@ use bevy_xpbd_3d::prelude::*; pub(super) fn plugin(app: &mut App) { app.add_systems( Update, - prepare_models_of_controllers - .after(PhysicsSet::Sync) - .before(TransformSystem::TransformPropagate) - .run_if(in_state(GameState::Playing)), + prepare_models_of_controllers.run_if(in_state(GameState::Playing)), ); } diff --git a/src/movement/navigation.rs b/src/movement/navigation.rs index e6ca682b..e07ec338 100644 --- a/src/movement/navigation.rs +++ b/src/movement/navigation.rs @@ -2,9 +2,9 @@ use crate::dev::dev_editor::DevEditorWindow; use crate::{ level_instantiation::on_spawn::{player, Npc, Player}, - movement::character_controller::{GeneralMovementSystemSet, Walk}, + movement::character_controller::Walk, util::math_trait_ext::{F32Ext, Vec3Ext}, - GameState, + GameState, GameSystemSet, }; #[cfg(feature = "dev")] use anyhow::Context; @@ -43,7 +43,7 @@ pub(super) fn plugin(app: &mut App) { .add_systems( Update, query_mesh - .before(GeneralMovementSystemSet) + .in_set(GameSystemSet::Navigation) .run_if(in_state(GameState::Playing)), ); #[cfg(feature = "dev")] diff --git a/src/particles.rs b/src/particles.rs index 4c89e5a9..54c86fc5 100644 --- a/src/particles.rs +++ b/src/particles.rs @@ -8,7 +8,6 @@ use bevy::prelude::*; use bevy_hanabi::prelude::*; use bevy_mod_sysfail::prelude::*; use bevy_tnua::prelude::*; -use bevy_xpbd_3d::PhysicsSet; pub(crate) use creation::*; mod creation; @@ -19,9 +18,7 @@ pub(super) fn plugin(app: &mut App) { .add_plugins(HanabiPlugin) .add_systems( Update, - play_sprinting_effect - .run_if(in_state(GameState::Playing)) - .after(PhysicsSet::Sync), + play_sprinting_effect.run_if(in_state(GameState::Playing)), ); } diff --git a/src/player_control/camera.rs b/src/player_control/camera.rs index 56b7f514..bb5bb70a 100644 --- a/src/player_control/camera.rs +++ b/src/player_control/camera.rs @@ -1,4 +1,5 @@ use crate::level_instantiation::on_spawn::Player; +use crate::GameSystemSet; use crate::{ player_control::camera::{ cursor::grab_cursor, @@ -9,11 +10,8 @@ use crate::{ GameState, }; use bevy::prelude::*; -use bevy::transform::TransformSystem; use bevy_atmosphere::prelude::AtmospherePlugin; use bevy_dolly::prelude::Dolly; -use bevy_xpbd_3d::PhysicsSet; -use bevy_yarnspinner_example_dialogue_view::ExampleYarnSpinnerDialogueViewSystemSet; pub(crate) use cursor::ForceCursorGrabMode; use serde::{Deserialize, Serialize}; use ui::*; @@ -68,20 +66,10 @@ pub(super) fn plugin(app: &mut App) { .add_systems(Update, grab_cursor.run_if(in_state(GameState::Playing))) .add_systems( Update, - ( - update_kind, - update_drivers, - set_camera_focus.after(ExampleYarnSpinnerDialogueViewSystemSet), - update_rig, - ) + (update_kind, update_drivers, set_camera_focus, update_rig) .chain() - .in_set(CameraUpdateSystemSet) - .after(PhysicsSet::Sync) - .before(TransformSystem::TransformPropagate) + .in_set(GameSystemSet::CameraUpdate) .run_if(in_state(GameState::Playing)) .run_if(any_with_component::), ); } - -#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] -pub(super) struct CameraUpdateSystemSet; diff --git a/src/player_control/camera/rig/arm.rs b/src/player_control/camera/rig/arm.rs index 44fed30f..bcd203e6 100644 --- a/src/player_control/camera/rig/arm.rs +++ b/src/player_control/camera/rig/arm.rs @@ -2,7 +2,6 @@ use crate::{ file_system_interaction::config::GameConfig, movement::physics::CollisionLayer, player_control::camera::{IngameCamera, IngameCameraKind}, - util::smoothness_to_lerp_factor, }; use bevy::prelude::*; use bevy_dolly::prelude::*; @@ -106,3 +105,9 @@ fn get_distance_such_that_min_distance_from_collision_is_ensured( let hypotenuse = adjacent_side / angle.cos(); hit.time_of_impact - hypotenuse } + +/// Taken from https://github.com/h3r2tic/dolly/blob/main/src/util.rs#L34 +fn smoothness_to_lerp_factor(smoothness: f32, dt: f32) -> f32 { + const SMOOTHNESS_MULTIPLIER: f32 = 8.0; + 1.0 - (-SMOOTHNESS_MULTIPLIER * dt / smoothness.max(1e-5)).exp() +} diff --git a/src/player_control/player_embodiment.rs b/src/player_control/player_embodiment.rs index 5fd1213f..df2fb257 100644 --- a/src/player_control/player_embodiment.rs +++ b/src/player_control/player_embodiment.rs @@ -3,8 +3,9 @@ use crate::{ movement::character_controller::*, player_control::{ actions::{DualAxisDataExt, PlayerAction}, - camera::{CameraUpdateSystemSet, IngameCamera, IngameCameraKind}, + camera::{IngameCamera, IngameCameraKind}, }, + GameSystemSet, }; use crate::{ @@ -16,7 +17,6 @@ use bevy::prelude::*; use bevy_kira_audio::AudioInstance; use bevy_mod_sysfail::prelude::*; use bevy_tnua::{builtins::TnuaBuiltinWalk, controller::TnuaController}; -use leafwing_input_manager::plugin::InputManagerSystem; use leafwing_input_manager::prelude::ActionState; /// This plugin handles everything that has to do with the player's physical representation in the world. @@ -34,9 +34,7 @@ pub(super) fn plugin(app: &mut App) { handle_camera_kind, ) .chain() - .before(CameraUpdateSystemSet) - .before(GeneralMovementSystemSet) - .after(InputManagerSystem::ManualControl) + .in_set(GameSystemSet::PlayerEmbodiment) .run_if(in_state(GameState::Playing)), ); } diff --git a/src/system_set.rs b/src/system_set.rs new file mode 100644 index 00000000..8844a8ad --- /dev/null +++ b/src/system_set.rs @@ -0,0 +1,58 @@ +use bevy::prelude::*; +use bevy_dolly::prelude::DollyUpdateSet; +use bevy_gltf_blueprints::GltfBlueprintsSet; +use bevy_yarnspinner_example_dialogue_view::ExampleYarnSpinnerDialogueViewSystemSet; + +pub(super) fn plugin(app: &mut App) { + app.configure_sets( + Update, + ( + ( + GltfBlueprintsSet::AfterSpawn, + GameSystemSet::ColliderSpawn, + GameSystemSet::Navigation, + GameSystemSet::PlayerEmbodiment, + GameSystemSet::GeneralMovement, + GameSystemSet::PrepareAnimationState, + ) + .chain(), + ( + GameSystemSet::UpdateAnimationState, + GameSystemSet::PlayAnimation, + ExampleYarnSpinnerDialogueViewSystemSet, + GameSystemSet::CameraUpdate, + DollyUpdateSet, + GameSystemSet::UpdateInteractionOpportunities, + ) + .chain(), + ) + .chain(), + ); +} + +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] +pub(crate) enum GameSystemSet { + /// - Goes through entities tagged with [`ColliderConstructor`](crate::physics::ColliderConstructor) in Blender + /// - Inserts a proper XPBD collider + /// - Inserts [`SensorLinks`](crate::physics::SensorLinks) on all [`RigidBody`](bevy_xpbd_3d::components::RigidBody)s + /// - Links sensor colliders to their closest [`SensorLinks`](crate::physics::SensorLinks) up the hierarchy + ColliderSpawn, + /// Run path finding + Navigation, + /// Update interaction opportunities with the environment + UpdateInteractionOpportunities, + /// Handle player input + PlayerEmbodiment, + /// Handle movement for character controllers + GeneralMovement, + /// Prepare the exclusive animation state for the current frame + PrepareAnimationState, + /// Update the animation state according to this frame's events since [`GameSystemSet::PrepareAnimationState`] + UpdateAnimationState, + /// Play animations + PlayAnimation, + /// Update the camera transform + CameraUpdate, + /// Interacts with Yarn Spinner for dialog logic + Dialog, +} diff --git a/src/util.rs b/src/util.rs index 7000e0e0..2a5a5747 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,8 +1,2 @@ pub(crate) mod criteria; pub(crate) mod math_trait_ext; - -pub(crate) fn smoothness_to_lerp_factor(smoothness: f32, dt: f32) -> f32 { - // Taken from https://github.com/h3r2tic/dolly/blob/main/src/util.rs#L34 - const SMOOTHNESS_MULTIPLIER: f32 = 8.0; - 1.0 - (-SMOOTHNESS_MULTIPLIER * dt / smoothness.max(1e-5)).exp() -} diff --git a/src/world_interaction/dialog.rs b/src/world_interaction/dialog.rs index f9060371..c5cd1006 100644 --- a/src/world_interaction/dialog.rs +++ b/src/world_interaction/dialog.rs @@ -1,9 +1,9 @@ use crate::player_control::actions::ActionsFrozen; +use crate::GameSystemSet; use bevy::prelude::*; use bevy_egui::EguiPlugin; use bevy_yarnspinner::{events::DialogueCompleteEvent, prelude::*}; use bevy_yarnspinner_example_dialogue_view::prelude::*; -use leafwing_input_manager::plugin::InputManagerSystem; use serde::{Deserialize, Serialize}; pub(super) fn plugin(app: &mut App) { @@ -16,9 +16,9 @@ pub(super) fn plugin(app: &mut App) { Update, ( spawn_dialogue_runner.run_if(resource_added::), - unfreeze_after_dialog.after(InputManagerSystem::ManualControl), + unfreeze_after_dialog, ) - .after(ExampleYarnSpinnerDialogueViewSystemSet), + .in_set(GameSystemSet::Dialog), ) .init_resource::() .register_type::() diff --git a/src/world_interaction/interaction_ui.rs b/src/world_interaction/interaction_ui.rs index 3a0c9c1b..b0790c9f 100644 --- a/src/world_interaction/interaction_ui.rs +++ b/src/world_interaction/interaction_ui.rs @@ -1,3 +1,4 @@ +use crate::system_set::GameSystemSet; use crate::{ level_instantiation::on_spawn::Player, player_control::{ @@ -8,7 +9,7 @@ use crate::{ world_interaction::dialog::{CurrentDialogTarget, YarnNode}, GameState, }; -use bevy::{prelude::*, transform::TransformSystem::TransformPropagate, window::PrimaryWindow}; +use bevy::{prelude::*, window::PrimaryWindow}; use bevy_egui::{egui, EguiContexts}; use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::*; @@ -23,12 +24,8 @@ pub(super) fn plugin(app: &mut App) { .init_resource::() .add_systems( Update, - ( - update_interaction_opportunities - .after(PhysicsSet::Sync) - .after(TransformPropagate), - display_interaction_prompt, - ) + (update_interaction_opportunities, display_interaction_prompt) + .in_set(GameSystemSet::UpdateInteractionOpportunities) .chain() .run_if( not(is_frozen) From b0d182b541071ce6c86dea403c7366c87c3ce649 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 15:28:09 +0200 Subject: [PATCH 3/7] Hook up some missing system sets --- src/level_instantiation/on_spawn/collider.rs | 10 ++++++--- .../character_controller/animation.rs | 3 ++- src/system_set.rs | 21 ++++--------------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/level_instantiation/on_spawn/collider.rs b/src/level_instantiation/on_spawn/collider.rs index 4dbfe320..56cf3def 100644 --- a/src/level_instantiation/on_spawn/collider.rs +++ b/src/level_instantiation/on_spawn/collider.rs @@ -1,4 +1,4 @@ -use crate::{movement::physics::CollisionLayer, GameState}; +use crate::{movement::physics::CollisionLayer, GameState, GameSystemSet}; use anyhow::Context; use bevy::prelude::*; use bevy_mod_sysfail::prelude::*; @@ -12,8 +12,12 @@ use std::iter; struct Collider; pub(super) fn plugin(app: &mut App) { - app.register_type::() - .add_systems(Update, spawn.run_if(in_state(GameState::Playing))); + app.register_type::().add_systems( + Update, + spawn + .in_set(GameSystemSet::ColliderSpawn) + .run_if(in_state(GameState::Playing)), + ); } #[sysfail(Log)] diff --git a/src/movement/character_controller/animation.rs b/src/movement/character_controller/animation.rs index d77c7deb..5eab4073 100644 --- a/src/movement/character_controller/animation.rs +++ b/src/movement/character_controller/animation.rs @@ -6,10 +6,11 @@ use bevy_tnua::{ TnuaAnimatingStateDirective, }; use std::time::Duration; +use crate::system_set::GameSystemSet; pub(super) fn plugin(app: &mut App) { app.register_type::() - .add_systems(Update, play_animations); + .add_systems(Update, play_animations.in_set(GameSystemSet::PlayAnimation)); } /// Managed by [`play_animations`] diff --git a/src/system_set.rs b/src/system_set.rs index 8844a8ad..41b14478 100644 --- a/src/system_set.rs +++ b/src/system_set.rs @@ -7,24 +7,17 @@ pub(super) fn plugin(app: &mut App) { app.configure_sets( Update, ( - ( GltfBlueprintsSet::AfterSpawn, GameSystemSet::ColliderSpawn, + GameSystemSet::UpdateInteractionOpportunities, GameSystemSet::Navigation, GameSystemSet::PlayerEmbodiment, GameSystemSet::GeneralMovement, - GameSystemSet::PrepareAnimationState, - ) - .chain(), - ( - GameSystemSet::UpdateAnimationState, GameSystemSet::PlayAnimation, + GameSystemSet::Dialog, ExampleYarnSpinnerDialogueViewSystemSet, GameSystemSet::CameraUpdate, DollyUpdateSet, - GameSystemSet::UpdateInteractionOpportunities, - ) - .chain(), ) .chain(), ); @@ -32,10 +25,8 @@ pub(super) fn plugin(app: &mut App) { #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] pub(crate) enum GameSystemSet { - /// - Goes through entities tagged with [`ColliderConstructor`](crate::physics::ColliderConstructor) in Blender - /// - Inserts a proper XPBD collider - /// - Inserts [`SensorLinks`](crate::physics::SensorLinks) on all [`RigidBody`](bevy_xpbd_3d::components::RigidBody)s - /// - Links sensor colliders to their closest [`SensorLinks`](crate::physics::SensorLinks) up the hierarchy + /// Goes through entities tagged with `Collider` in Blender + /// and inserts a proper XPBD collider ColliderSpawn, /// Run path finding Navigation, @@ -45,10 +36,6 @@ pub(crate) enum GameSystemSet { PlayerEmbodiment, /// Handle movement for character controllers GeneralMovement, - /// Prepare the exclusive animation state for the current frame - PrepareAnimationState, - /// Update the animation state according to this frame's events since [`GameSystemSet::PrepareAnimationState`] - UpdateAnimationState, /// Play animations PlayAnimation, /// Update the camera transform From 4329250d21172f49583a9ff324ce4a90edbcb0e3 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 18:29:05 +0200 Subject: [PATCH 4/7] Fix dialogue runner not being created --- src/dev/dev_editor.rs | 7 +-- src/level_instantiation/on_spawn/collider.rs | 10 +-- src/lib.rs | 1 + src/movement/character_controller.rs | 4 +- .../character_controller/animation.rs | 2 +- src/movement/navigation.rs | 9 +-- src/player_control/camera.rs | 14 +++-- src/player_control/camera/cursor.rs | 10 +-- src/player_control/camera/focus.rs | 17 +++--- src/player_control/camera/rig/arm.rs | 2 +- src/player_control/player_embodiment.rs | 13 ++-- src/system_set.rs | 42 +++++++++---- src/util.rs | 25 ++++++++ src/world_interaction/dialog.rs | 4 +- src/world_interaction/interaction_ui.rs | 61 ++++--------------- 15 files changed, 106 insertions(+), 115 deletions(-) diff --git a/src/dev/dev_editor.rs b/src/dev/dev_editor.rs index d6b4d16f..ee902f27 100644 --- a/src/dev/dev_editor.rs +++ b/src/dev/dev_editor.rs @@ -1,4 +1,4 @@ -use crate::{player_control::camera::ForceCursorGrabMode, GameState}; +use crate::player_control::camera::ForceCursorGrabMode; use anyhow::Context; use bevy::{prelude::*, window::CursorGrabMode}; use bevy_editor_pls::{ @@ -14,10 +14,7 @@ use serde::{Deserialize, Serialize}; pub(super) fn plugin(app: &mut App) { app.init_resource::() .add_editor_window::() - .add_systems( - Update, - (handle_debug_render, set_cursor_grab_mode).run_if(in_state(GameState::Playing)), - ); + .add_systems(Update, (handle_debug_render, set_cursor_grab_mode)); } pub(crate) struct DevEditorWindow; diff --git a/src/level_instantiation/on_spawn/collider.rs b/src/level_instantiation/on_spawn/collider.rs index 56cf3def..3693ea61 100644 --- a/src/level_instantiation/on_spawn/collider.rs +++ b/src/level_instantiation/on_spawn/collider.rs @@ -1,4 +1,4 @@ -use crate::{movement::physics::CollisionLayer, GameState, GameSystemSet}; +use crate::{movement::physics::CollisionLayer, GameSystemSet}; use anyhow::Context; use bevy::prelude::*; use bevy_mod_sysfail::prelude::*; @@ -12,12 +12,8 @@ use std::iter; struct Collider; pub(super) fn plugin(app: &mut App) { - app.register_type::().add_systems( - Update, - spawn - .in_set(GameSystemSet::ColliderSpawn) - .run_if(in_state(GameState::Playing)), - ); + app.register_type::() + .add_systems(Update, spawn.in_set(GameSystemSet::ColliderSpawn)); } #[sysfail(Log)] diff --git a/src/lib.rs b/src/lib.rs index 463bb557..9f899645 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ enum GameState { /// Main entrypoint for Foxtrot. /// /// The top-level plugins are: +/// - [`system_set::plugin`]: Sets up the system set used to order systems across Foxtrot. /// - [`bevy_config::plugin`]: Sets up the bevy configuration. /// - [`menu::plugin`]: Handles the menu. /// - [`movement::plugin`]: Handles the movement of entities. diff --git a/src/movement/character_controller.rs b/src/movement/character_controller.rs index 5805a72a..32b1005c 100644 --- a/src/movement/character_controller.rs +++ b/src/movement/character_controller.rs @@ -1,5 +1,4 @@ use crate::system_set::GameSystemSet; -use crate::GameState; pub(crate) use animation::AnimationState; use bevy::prelude::*; use bevy_tnua::prelude::*; @@ -19,8 +18,7 @@ pub(super) fn plugin(app: &mut App) { Update, (apply_jumping, apply_walking) .chain() - .in_set(GameSystemSet::GeneralMovement) - .run_if(in_state(GameState::Playing)), + .in_set(GameSystemSet::GeneralMovement), ); } diff --git a/src/movement/character_controller/animation.rs b/src/movement/character_controller/animation.rs index 5eab4073..ec90887f 100644 --- a/src/movement/character_controller/animation.rs +++ b/src/movement/character_controller/animation.rs @@ -1,3 +1,4 @@ +use crate::system_set::GameSystemSet; use bevy::{animation::AnimationPlayer, prelude::*}; use bevy_gltf_blueprints::{AnimationPlayerLink, Animations}; use bevy_mod_sysfail::prelude::*; @@ -6,7 +7,6 @@ use bevy_tnua::{ TnuaAnimatingStateDirective, }; use std::time::Duration; -use crate::system_set::GameSystemSet; pub(super) fn plugin(app: &mut App) { app.register_type::() diff --git a/src/movement/navigation.rs b/src/movement/navigation.rs index e07ec338..2cf134b2 100644 --- a/src/movement/navigation.rs +++ b/src/movement/navigation.rs @@ -4,7 +4,7 @@ use crate::{ level_instantiation::on_spawn::{player, Npc, Player}, movement::character_controller::Walk, util::math_trait_ext::{F32Ext, Vec3Ext}, - GameState, GameSystemSet, + GameSystemSet, }; #[cfg(feature = "dev")] use anyhow::Context; @@ -40,12 +40,7 @@ pub(super) fn plugin(app: &mut App) { max_edge_length: 100, max_tile_generation_tasks: None, })) - .add_systems( - Update, - query_mesh - .in_set(GameSystemSet::Navigation) - .run_if(in_state(GameState::Playing)), - ); + .add_systems(Update, query_mesh.in_set(GameSystemSet::Navigation)); #[cfg(feature = "dev")] app.add_plugins(OxidizedNavigationDebugDrawPlugin) .add_systems(Update, draw_navmesh); diff --git a/src/player_control/camera.rs b/src/player_control/camera.rs index bb5bb70a..ee0657ca 100644 --- a/src/player_control/camera.rs +++ b/src/player_control/camera.rs @@ -1,4 +1,3 @@ -use crate::level_instantiation::on_spawn::Player; use crate::GameSystemSet; use crate::{ player_control::camera::{ @@ -63,13 +62,16 @@ pub(super) fn plugin(app: &mut App) { .add_systems(Update, Dolly::::update_active) .add_systems(Startup, spawn_ui_camera) .add_systems(OnEnter(GameState::Playing), despawn_ui_camera) - .add_systems(Update, grab_cursor.run_if(in_state(GameState::Playing))) .add_systems( Update, - (update_kind, update_drivers, set_camera_focus, update_rig) + ( + grab_cursor, + update_kind, + update_drivers, + set_camera_focus, + update_rig, + ) .chain() - .in_set(GameSystemSet::CameraUpdate) - .run_if(in_state(GameState::Playing)) - .run_if(any_with_component::), + .in_set(GameSystemSet::CameraUpdate), ); } diff --git a/src/player_control/camera/cursor.rs b/src/player_control/camera/cursor.rs index 1e7fcfae..db20550e 100644 --- a/src/player_control/camera/cursor.rs +++ b/src/player_control/camera/cursor.rs @@ -1,26 +1,20 @@ use crate::player_control::actions::ActionsFrozen; -use anyhow::Context; +use crate::util::single_mut; use bevy::{ prelude::*, window::{CursorGrabMode, PrimaryWindow}, }; -use bevy_mod_sysfail::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Resource, Serialize, Deserialize, Default)] pub(crate) struct ForceCursorGrabMode(pub(crate) Option); -#[sysfail(Log)] pub(super) fn grab_cursor( mut primary_windows: Query<&mut Window, With>, actions_frozen: Res, force_cursor_grab: Res, ) { - #[cfg(feature = "tracing")] - let _span = info_span!("cursor_grab_system").entered(); - let mut window = primary_windows - .get_single_mut() - .context("Failed to get primary window")?; + let mut window = single_mut!(primary_windows); let cursor = &mut window.cursor; if let Some(mode) = force_cursor_grab.0 { cursor.grab_mode = mode; diff --git a/src/player_control/camera/focus.rs b/src/player_control/camera/focus.rs index 5872e3c5..de544132 100644 --- a/src/player_control/camera/focus.rs +++ b/src/player_control/camera/focus.rs @@ -1,13 +1,12 @@ +use crate::util::{single, single_mut}; use crate::{ level_instantiation::on_spawn::{player, Player}, player_control::camera::IngameCamera, world_interaction::dialog::CurrentDialogTarget, }; use bevy::prelude::*; -use bevy_mod_sysfail::prelude::*; use bevy_yarnspinner::events::DialogueCompleteEvent; -#[sysfail(Log)] pub(super) fn set_camera_focus( mut camera_query: Query<&mut IngameCamera>, player_query: Query<&Transform, With>, @@ -15,14 +14,14 @@ pub(super) fn set_camera_focus( dialog_target: Res, mut dialogue_complete_event: EventReader, ) { - for mut camera in camera_query.iter_mut() { - let player_transform = player_query.get_single()?; - if let Some(dialog_target) = dialog_target.0 { - let dialog_target_transform = dialog_targets.get(dialog_target)?; - camera.secondary_target = Some(dialog_target_transform.translation); - } - camera.target = player_transform.translation + Vec3::Y * player::HEIGHT / 2.; + let mut camera = single_mut!(camera_query); + let player_transform = single!(player_query); + if let Some(dialog_target) = dialog_target.0 { + let dialog_target_transform = dialog_targets.get(dialog_target).unwrap(); + camera.secondary_target = Some(dialog_target_transform.translation); } + camera.target = player_transform.translation + Vec3::Y * player::HEIGHT / 2.; + for _event in dialogue_complete_event.read() { for mut camera in camera_query.iter_mut() { camera.secondary_target = None; diff --git a/src/player_control/camera/rig/arm.rs b/src/player_control/camera/rig/arm.rs index bcd203e6..420fd019 100644 --- a/src/player_control/camera/rig/arm.rs +++ b/src/player_control/camera/rig/arm.rs @@ -106,7 +106,7 @@ fn get_distance_such_that_min_distance_from_collision_is_ensured( hit.time_of_impact - hypotenuse } -/// Taken from https://github.com/h3r2tic/dolly/blob/main/src/util.rs#L34 +/// Taken from fn smoothness_to_lerp_factor(smoothness: f32, dt: f32) -> f32 { const SMOOTHNESS_MULTIPLIER: f32 = 8.0; 1.0 - (-SMOOTHNESS_MULTIPLIER * dt / smoothness.max(1e-5)).exp() diff --git a/src/player_control/player_embodiment.rs b/src/player_control/player_embodiment.rs index df2fb257..8771b1ed 100644 --- a/src/player_control/player_embodiment.rs +++ b/src/player_control/player_embodiment.rs @@ -8,9 +8,10 @@ use crate::{ GameSystemSet, }; +use crate::util::single_mut; use crate::{ level_instantiation::on_spawn::Player, util::math_trait_ext::Vec3Ext, - world_interaction::dialog::CurrentDialogTarget, GameState, + world_interaction::dialog::CurrentDialogTarget, }; use anyhow::Context; use bevy::prelude::*; @@ -34,8 +35,7 @@ pub(super) fn plugin(app: &mut App) { handle_camera_kind, ) .chain() - .in_set(GameSystemSet::PlayerEmbodiment) - .run_if(in_state(GameState::Playing)), + .in_set(GameSystemSet::PlayerEmbodiment), ); } @@ -113,20 +113,19 @@ fn handle_camera_kind( } } -#[sysfail(Log)] fn rotate_to_speaker( dialog_target: Res, mut with_player: Query<(&Transform, &mut TnuaController, &FloatHeight), With>, speakers: Query<&Transform, Without>, ) { let Some(dialog_target) = dialog_target.0 else { - return Ok(()); + return; }; #[cfg(feature = "tracing")] let _span = info_span!("rotate_to_speaker").entered(); - let (player_transform, mut controller, float_height) = with_player.get_single_mut()?; - let speaker_transform = speakers.get(dialog_target)?; + let (player_transform, mut controller, float_height) = single_mut!(with_player); + let speaker_transform = speakers.get(dialog_target).unwrap(); let direction = (speaker_transform.translation - player_transform.translation).horizontal(); controller.basis(TnuaBuiltinWalk { desired_forward: direction.normalize_or_zero(), diff --git a/src/system_set.rs b/src/system_set.rs index 41b14478..abd6227d 100644 --- a/src/system_set.rs +++ b/src/system_set.rs @@ -1,28 +1,48 @@ +use crate::GameState; use bevy::prelude::*; use bevy_dolly::prelude::DollyUpdateSet; use bevy_gltf_blueprints::GltfBlueprintsSet; +use bevy_yarnspinner::prelude::YarnSpinnerSystemSet; use bevy_yarnspinner_example_dialogue_view::ExampleYarnSpinnerDialogueViewSystemSet; pub(super) fn plugin(app: &mut App) { app.configure_sets( Update, ( - GltfBlueprintsSet::AfterSpawn, - GameSystemSet::ColliderSpawn, - GameSystemSet::UpdateInteractionOpportunities, - GameSystemSet::Navigation, - GameSystemSet::PlayerEmbodiment, - GameSystemSet::GeneralMovement, - GameSystemSet::PlayAnimation, - GameSystemSet::Dialog, - ExampleYarnSpinnerDialogueViewSystemSet, - GameSystemSet::CameraUpdate, - DollyUpdateSet, + GltfBlueprintsSet::AfterSpawn, + YarnSpinnerSystemSet, + GameSystemSet::ColliderSpawn, + GameSystemSet::Navigation, + GameSystemSet::PlayerEmbodiment, + GameSystemSet::GeneralMovement, + GameSystemSet::PlayAnimation, + GameSystemSet::UpdateInteractionOpportunities, + GameSystemSet::Dialog, + ExampleYarnSpinnerDialogueViewSystemSet, + GameSystemSet::CameraUpdate, + DollyUpdateSet, ) .chain(), + ) + .configure_sets( + Update, + ( + GameSystemSet::ColliderSpawn, + GameSystemSet::UpdateInteractionOpportunities, + GameSystemSet::Navigation, + GameSystemSet::PlayerEmbodiment, + GameSystemSet::GeneralMovement, + GameSystemSet::PlayAnimation, + GameSystemSet::Dialog, + GameSystemSet::CameraUpdate, + ) + .run_if(in_state(GameState::Playing)), ); } +/// Used for ordering systems across Foxtrot. +/// Note that the order of items of this enum is not necessarily the order of execution. +/// Look at [`crate::system_set::plugin`] for the actual order used. #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] pub(crate) enum GameSystemSet { /// Goes through entities tagged with `Collider` in Blender diff --git a/src/util.rs b/src/util.rs index 2a5a5747..5cc96f54 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,2 +1,27 @@ pub(crate) mod criteria; pub(crate) mod math_trait_ext; + +macro_rules! single { + ($query:expr) => { + match $query.get_single() { + Ok(q) => q, + _ => { + return; + } + } + }; +} + +macro_rules! single_mut { + ($query:expr) => { + match $query.get_single_mut() { + Ok(q) => q, + _ => { + return; + } + } + }; +} + +pub(crate) use single; +pub(crate) use single_mut; diff --git a/src/world_interaction/dialog.rs b/src/world_interaction/dialog.rs index c5cd1006..4e5b4b6f 100644 --- a/src/world_interaction/dialog.rs +++ b/src/world_interaction/dialog.rs @@ -16,9 +16,9 @@ pub(super) fn plugin(app: &mut App) { Update, ( spawn_dialogue_runner.run_if(resource_added::), - unfreeze_after_dialog, + unfreeze_after_dialog.in_set(GameSystemSet::Dialog), ) - .in_set(GameSystemSet::Dialog), + .chain(), ) .init_resource::() .register_type::() diff --git a/src/world_interaction/interaction_ui.rs b/src/world_interaction/interaction_ui.rs index b0790c9f..f6a1fb25 100644 --- a/src/world_interaction/interaction_ui.rs +++ b/src/world_interaction/interaction_ui.rs @@ -1,4 +1,5 @@ use crate::system_set::GameSystemSet; +use crate::util::{single, single_mut}; use crate::{ level_instantiation::on_spawn::Player, player_control::{ @@ -7,11 +8,9 @@ use crate::{ }, util::criteria::is_frozen, world_interaction::dialog::{CurrentDialogTarget, YarnNode}, - GameState, }; use bevy::{prelude::*, window::PrimaryWindow}; use bevy_egui::{egui, EguiContexts}; -use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::*; use bevy_yarnspinner::prelude::DialogueRunner; use leafwing_input_manager::prelude::ActionState; @@ -25,13 +24,9 @@ pub(super) fn plugin(app: &mut App) { .add_systems( Update, (update_interaction_opportunities, display_interaction_prompt) - .in_set(GameSystemSet::UpdateInteractionOpportunities) .chain() - .run_if( - not(is_frozen) - .and_then(in_state(GameState::Playing)) - .and_then(any_with_component::), - ), + .in_set(GameSystemSet::UpdateInteractionOpportunities) + .run_if(not(is_frozen)), ); } @@ -39,10 +34,8 @@ pub(super) fn plugin(app: &mut App) { #[reflect(Resource, Serialize, Deserialize)] struct InteractionOpportunity(Option); -#[sysfail(Log)] fn update_interaction_opportunities( - mut collisions: EventReader, - player_query: Query<&GlobalTransform, With>, + player_query: Query<(&GlobalTransform, &CollidingEntities), With>, parents: Query<&Parent>, target_query: Query< (Entity, &GlobalTransform), @@ -52,15 +45,11 @@ fn update_interaction_opportunities( mut interaction_opportunity: ResMut, ) { interaction_opportunity.0 = None; + let (player_transform, collisions) = single!(player_query); + let player_translation = player_transform.translation(); + let (camera, camera_transform) = single!(camera_query); - for Collision(ref contacts) in collisions.read() { - // Check if the player is colliding with anything - let Some((player, sensor)) = - get_player_and_target(&player_query, contacts.entity1, contacts.entity2) - else { - continue; - }; - + for &sensor in collisions.0.iter() { // A dialog collider is valid for any of its ancestors let mut ancestors = iter::once(sensor).chain(parents.iter_ancestors(sensor)); @@ -71,15 +60,7 @@ fn update_interaction_opportunities( continue; }; - if !contacts.during_current_frame { - continue; - } - // Check if we are facing the right way - let player_translation = player_query.get(player).unwrap().translation(); - let Some((camera, camera_transform)) = camera_query.iter().next() else { - continue; - }; let is_facing_target = is_facing_target( player_translation, target_transform.translation(), @@ -88,24 +69,11 @@ fn update_interaction_opportunities( ); if is_facing_target { interaction_opportunity.0.replace(target); + break; } } } -fn get_player_and_target( - player_query: &Query<&GlobalTransform, With>, - entity_a: Entity, - entity_b: Entity, -) -> Option<(Entity, Entity)> { - if player_query.contains(entity_a) { - Some((entity_a, entity_b)) - } else if player_query.contains(entity_b) { - Some((entity_b, entity_a)) - } else { - None - } -} - fn is_facing_target( player: Vec3, target: Vec3, @@ -121,7 +89,6 @@ fn is_facing_target( angle < TAU / 8. } -#[sysfail(Log)] fn display_interaction_prompt( interaction_opportunity: Res, mut dialogue_runner: Query<&mut DialogueRunner>, @@ -133,13 +100,12 @@ fn display_interaction_prompt( mut current_dialog_target: ResMut, ) { let Some(opportunity) = interaction_opportunity.0 else { - return Ok(()); - }; - let Ok(window) = primary_windows.get_single() else { - return Ok(()); + return; }; + let window = single!(primary_windows); + let mut dialogue_runner = single_mut!(dialogue_runner); - let (entity, dialog_target) = dialog_target_query.get(opportunity)?; + let (entity, dialog_target) = dialog_target_query.get(opportunity).unwrap(); egui::Window::new("Interaction") .collapsible(false) .title_bar(false) @@ -150,7 +116,6 @@ fn display_interaction_prompt( }); for actions in actions.iter() { if actions.just_pressed(&PlayerAction::Interact) { - let mut dialogue_runner = dialogue_runner.single_mut(); dialogue_runner.start_node(&dialog_target.0); current_dialog_target.0.replace(entity); freeze.freeze(); From 614fcf3fa348e7036da2cd5fe0376a424030aab2 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 18:59:28 +0200 Subject: [PATCH 5/7] Remove sysfail --- Cargo.lock | 25 ------------------- Cargo.toml | 1 - readme.md | 1 - src/bevy_config.rs | 15 ++++++----- src/dev/dev_editor.rs | 11 +++++--- src/file_system_interaction/asset_loading.rs | 2 -- src/level_instantiation/on_spawn/collider.rs | 12 +++++---- .../character_controller/animation.rs | 14 +++++++---- src/movement/navigation.rs | 19 ++++++++------ src/particles.rs | 4 +-- src/player_control/actions.rs | 2 +- src/player_control/camera/rig.rs | 4 +-- src/player_control/player_embodiment.rs | 17 +++++-------- src/util.rs | 7 ++++-- src/util/pipe.rs | 8 ++++++ src/world_interaction/interaction_ui.rs | 2 +- 16 files changed, 64 insertions(+), 80 deletions(-) create mode 100644 src/util/pipe.rs diff --git a/Cargo.lock b/Cargo.lock index c9323da5..d5ac84d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1063,30 +1063,6 @@ dependencies = [ "pretty-type-name", ] -[[package]] -name = "bevy_mod_sysfail" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a58f0be698c10aab373413556a89e193a783a7241ed3ed5971330a284a7c3b" -dependencies = [ - "anyhow", - "bevy", - "bevy_ecs", - "bevy_mod_sysfail_macros", - "bevy_utils", -] - -[[package]] -name = "bevy_mod_sysfail_macros" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595deba61fcc75116469575cec8abfa9ea2b74b905501daa6e34f0fa588f34d8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "bevy_pbr" version = "0.13.2" @@ -2440,7 +2416,6 @@ dependencies = [ "bevy_gltf_blueprints", "bevy_hanabi", "bevy_kira_audio", - "bevy_mod_sysfail", "bevy_registry_export", "bevy_xpbd_3d", "bevy_yarnspinner", diff --git a/Cargo.toml b/Cargo.toml index de49177b..821f3991 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,6 @@ oxidized_navigation = { version = "0.10", features = ["xpbd"] } iyes_progress = "0.11" leafwing-input-manager = { version = "0.13", features = ["egui"] } bevy_dolly = "0.0.3" -bevy_mod_sysfail = "7" bevy_editor_pls = { version = "0.8.1", optional = true } bevy_hanabi = { version = "0.11", default-features = false, features = ["3d"] } bevy_yarnspinner = "0.2" diff --git a/readme.md b/readme.md index c573bd03..97b6b510 100644 --- a/readme.md +++ b/readme.md @@ -17,7 +17,6 @@ https://user-images.githubusercontent.com/9047632/226387411-70f662de-0681-47ff-b - Shaders, using the code from [DGriffin's tutorial](https://www.youtube.com/watch?v=O6A_nVmpvhc) - GLTF imports, including auto-insertion of markers via the GLTF extras field - Smooth cameras via [`bevy_dolly`](https://crates.io/crates/bevy_dolly) -- Simple error handling via [`bevy_mod_sysfail`](https://crates.io/crates/bevy_mod_sysfail) - Particle effects via [`bevy_hanabi`](https://crates.io/crates/bevy_hanabi) - Procedural skies via [`bevy_atmosphere`](https://crates.io/crates/bevy_atmosphere) - Grass via [`warbler_grass`](https://crates.io/crates/warbler_grass) diff --git a/src/bevy_config.rs b/src/bevy_config.rs index 8459c8db..30d908ed 100644 --- a/src/bevy_config.rs +++ b/src/bevy_config.rs @@ -1,8 +1,7 @@ -use anyhow::Context; +use crate::util::error; use bevy::render::settings::{WgpuFeatures, WgpuSettings}; use bevy::render::RenderPlugin; use bevy::{prelude::*, window::PrimaryWindow, winit::WinitWindows}; -use bevy_mod_sysfail::prelude::*; use std::io::Cursor; use winit::window::Icon; @@ -24,7 +23,7 @@ pub(super) fn plugin(app: &mut App) { ) .insert_resource(Msaa::Sample4) .insert_resource(ClearColor(Color::rgb(0.4, 0.4, 0.4))) - .add_systems(Startup, set_window_icon); + .add_systems(Startup, set_window_icon.pipe(error)); } fn create_wgpu_settings() -> WgpuSettings { @@ -36,15 +35,14 @@ fn create_wgpu_settings() -> WgpuSettings { } // Sets the icon on Windows and X11 -#[sysfail(Log)] fn set_window_icon( windows: NonSend, primary_windows: Query>, -) { +) -> anyhow::Result<()> { let primary_entity = primary_windows.single(); - let primary = windows - .get_window(primary_entity) - .context("Failed to get primary window")?; + let Some(primary) = windows.get_window(primary_entity) else { + return Ok(()); + }; let icon_buf = Cursor::new(include_bytes!( "../build/macos/AppIcon.iconset/icon_256x256.png" )); @@ -55,4 +53,5 @@ fn set_window_icon( let icon = Icon::from_rgba(rgba, width, height)?; primary.set_window_icon(Some(icon)); }; + Ok(()) } diff --git a/src/dev/dev_editor.rs b/src/dev/dev_editor.rs index ee902f27..a8b3267e 100644 --- a/src/dev/dev_editor.rs +++ b/src/dev/dev_editor.rs @@ -1,4 +1,5 @@ use crate::player_control::camera::ForceCursorGrabMode; +use crate::util::error; use anyhow::Context; use bevy::{prelude::*, window::CursorGrabMode}; use bevy_editor_pls::{ @@ -7,14 +8,16 @@ use bevy_editor_pls::{ AddEditorWindow, }; use bevy_egui::egui; -use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::PhysicsGizmos; use serde::{Deserialize, Serialize}; pub(super) fn plugin(app: &mut App) { app.init_resource::() .add_editor_window::() - .add_systems(Update, (handle_debug_render, set_cursor_grab_mode)); + .add_systems( + Update, + (handle_debug_render.pipe(error), set_cursor_grab_mode), + ); } pub(crate) struct DevEditorWindow; @@ -48,12 +51,11 @@ pub(crate) struct DevEditorState { pub(crate) navmesh_render_enabled: bool, } -#[sysfail(Log)] fn handle_debug_render( state: Res, mut last_enabled: Local, mut config_store: ResMut, -) { +) -> anyhow::Result<()> { let current_enabled = state .window_state::() .context("Failed to read dev window state")? @@ -64,6 +66,7 @@ fn handle_debug_render( *last_enabled = current_enabled; let config = config_store.config_mut::().0; config.enabled = current_enabled; + Ok(()) } fn set_cursor_grab_mode( diff --git a/src/file_system_interaction/asset_loading.rs b/src/file_system_interaction/asset_loading.rs index 2c29ed80..9647a13f 100644 --- a/src/file_system_interaction/asset_loading.rs +++ b/src/file_system_interaction/asset_loading.rs @@ -4,7 +4,6 @@ use bevy_asset_loader::prelude::*; use bevy_common_assets::toml::TomlAssetPlugin; use bevy_egui::{egui, egui::ProgressBar, EguiContexts}; use bevy_kira_audio::AudioSource; -use bevy_mod_sysfail::prelude::*; use iyes_progress::{ProgressCounter, ProgressPlugin}; /// Loads resources and assets for the game. @@ -95,7 +94,6 @@ fn show_progress( } } -#[sysfail(Log)] fn update_config( mut commands: Commands, config: Res>, diff --git a/src/level_instantiation/on_spawn/collider.rs b/src/level_instantiation/on_spawn/collider.rs index 3693ea61..101dae05 100644 --- a/src/level_instantiation/on_spawn/collider.rs +++ b/src/level_instantiation/on_spawn/collider.rs @@ -1,7 +1,7 @@ +use crate::util::error; use crate::{movement::physics::CollisionLayer, GameSystemSet}; use anyhow::Context; use bevy::prelude::*; -use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::{Collider as XpbdCollider, *}; use oxidized_navigation::NavMeshAffector; use serde::{Deserialize, Serialize}; @@ -12,18 +12,19 @@ use std::iter; struct Collider; pub(super) fn plugin(app: &mut App) { - app.register_type::() - .add_systems(Update, spawn.in_set(GameSystemSet::ColliderSpawn)); + app.register_type::().add_systems( + Update, + spawn.pipe(error).in_set(GameSystemSet::ColliderSpawn), + ); } -#[sysfail(Log)] fn spawn( collider_marker: Query>, mut commands: Commands, children: Query<&Children>, meshes: Res>, mesh_handles: Query<&Handle>, -) { +) -> anyhow::Result<()> { #[cfg(feature = "tracing")] let _span = info_span!("read_colliders").entered(); for parent in collider_marker.iter() { @@ -49,4 +50,5 @@ fn spawn( .remove::() .insert(RigidBody::Static); } + Ok(()) } diff --git a/src/movement/character_controller/animation.rs b/src/movement/character_controller/animation.rs index ec90887f..5e32af59 100644 --- a/src/movement/character_controller/animation.rs +++ b/src/movement/character_controller/animation.rs @@ -1,7 +1,7 @@ use crate::system_set::GameSystemSet; +use crate::util::error; use bevy::{animation::AnimationPlayer, prelude::*}; use bevy_gltf_blueprints::{AnimationPlayerLink, Animations}; -use bevy_mod_sysfail::prelude::*; use bevy_tnua::{ builtins::TnuaBuiltinWalk, controller::TnuaController, TnuaAnimatingState, TnuaAnimatingStateDirective, @@ -9,8 +9,12 @@ use bevy_tnua::{ use std::time::Duration; pub(super) fn plugin(app: &mut App) { - app.register_type::() - .add_systems(Update, play_animations.in_set(GameSystemSet::PlayAnimation)); + app.register_type::().add_systems( + Update, + play_animations + .pipe(error) + .in_set(GameSystemSet::PlayAnimation), + ); } /// Managed by [`play_animations`] @@ -30,7 +34,6 @@ struct CharacterAnimationNames { aerial: String, } -#[sysfail(Log)] fn play_animations( mut query: Query<( Entity, @@ -42,7 +45,7 @@ fn play_animations( children: Query<&Children>, animation_names: Query<&CharacterAnimationNames>, mut animation_players: Query<&mut AnimationPlayer>, -) { +) -> anyhow::Result<()> { #[cfg(feature = "tracing")] let _span = info_span!("play_animations").entered(); for (entity, mut animating_state, controller, link, animations) in query.iter_mut() { @@ -120,4 +123,5 @@ fn play_animations( }, } } + Ok(()) } diff --git a/src/movement/navigation.rs b/src/movement/navigation.rs index 2cf134b2..4f9ce3a7 100644 --- a/src/movement/navigation.rs +++ b/src/movement/navigation.rs @@ -1,15 +1,15 @@ #[cfg(feature = "dev")] use crate::dev::dev_editor::DevEditorWindow; +use crate::util::error; use crate::{ level_instantiation::on_spawn::{player, Npc, Player}, movement::character_controller::Walk, - util::math_trait_ext::{F32Ext, Vec3Ext}, + util::{F32Ext, Vec3Ext}, GameSystemSet, }; #[cfg(feature = "dev")] use anyhow::Context; use bevy::prelude::*; -use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::Collider; #[cfg(feature = "dev")] use oxidized_navigation::debug_draw::{DrawNavMesh, DrawPath, OxidizedNavigationDebugDrawPlugin}; @@ -40,13 +40,15 @@ pub(super) fn plugin(app: &mut App) { max_edge_length: 100, max_tile_generation_tasks: None, })) - .add_systems(Update, query_mesh.in_set(GameSystemSet::Navigation)); + .add_systems( + Update, + query_mesh.pipe(error).in_set(GameSystemSet::Navigation), + ); #[cfg(feature = "dev")] app.add_plugins(OxidizedNavigationDebugDrawPlugin) - .add_systems(Update, draw_navmesh); + .add_systems(Update, draw_navmesh.pipe(error)); } -#[sysfail(Log)] fn query_mesh( #[cfg(feature = "dev")] mut commands: Commands, mut with_follower: Query<(&Transform, &mut Walk), (With, Without)>, @@ -54,7 +56,7 @@ fn query_mesh( nav_mesh_settings: Res, nav_mesh: Res, #[cfg(feature = "dev")] editor_state: Res, -) { +) -> anyhow::Result<()> { #[cfg(feature = "tracing")] let _span = info_span!("query_mesh").entered(); if let Ok(nav_mesh) = nav_mesh.get().read() { @@ -100,17 +102,18 @@ fn query_mesh( } } } + Ok(()) } #[cfg(feature = "dev")] -#[sysfail(Log)] fn draw_navmesh( editor: Res, mut draw_nav_mesh: ResMut, -) { +) -> anyhow::Result<()> { let nav_render_enabled = editor .window_state::() .context("Failed to read dev window state")? .navmesh_render_enabled; draw_nav_mesh.0 = nav_render_enabled; + Ok(()) } diff --git a/src/particles.rs b/src/particles.rs index 54c86fc5..f2522d48 100644 --- a/src/particles.rs +++ b/src/particles.rs @@ -1,12 +1,11 @@ use crate::{ file_system_interaction::config::GameConfig, level_instantiation::on_spawn::Player, - util::math_trait_ext::{F32Ext, Vec3Ext}, + util::{F32Ext, Vec3Ext}, GameState, }; use bevy::prelude::*; use bevy_hanabi::prelude::*; -use bevy_mod_sysfail::prelude::*; use bevy_tnua::prelude::*; pub(crate) use creation::*; @@ -26,7 +25,6 @@ pub(super) fn plugin(app: &mut App) { #[reflect(Component)] struct SprintingParticle; -#[sysfail(Log)] fn play_sprinting_effect( with_player: Query<&TnuaController, With>, mut with_particle: Query<&mut EffectSpawner, With>, diff --git a/src/player_control/actions.rs b/src/player_control/actions.rs index 0af18e23..aa9428e8 100644 --- a/src/player_control/actions.rs +++ b/src/player_control/actions.rs @@ -1,4 +1,4 @@ -use crate::util::criteria::is_frozen; +use crate::util::is_frozen; use bevy::prelude::*; use leafwing_input_manager::plugin::InputManagerSystem; use leafwing_input_manager::{axislike::DualAxisData, prelude::*}; diff --git a/src/player_control/camera/rig.rs b/src/player_control/camera/rig.rs index c6a686cd..480ac7a7 100644 --- a/src/player_control/camera/rig.rs +++ b/src/player_control/camera/rig.rs @@ -7,19 +7,17 @@ use crate::{ IngameCamera, IngameCameraKind, }, }, - util::math_trait_ext::Vec2Ext, + util::Vec2Ext, }; use crate::player_control::actions::ActionsFrozen; use bevy::prelude::*; use bevy_dolly::prelude::*; -use bevy_mod_sysfail::prelude::*; use bevy_xpbd_3d::prelude::SpatialQuery; use leafwing_input_manager::prelude::ActionState; mod arm; -#[sysfail(Log)] pub(super) fn update_rig( time: Res>, mut camera_query: Query<( diff --git a/src/player_control/player_embodiment.rs b/src/player_control/player_embodiment.rs index 8771b1ed..292a884c 100644 --- a/src/player_control/player_embodiment.rs +++ b/src/player_control/player_embodiment.rs @@ -1,3 +1,4 @@ +use crate::util::{error, single, single_mut}; use crate::{ file_system_interaction::audio::AudioHandles, movement::character_controller::*, @@ -7,16 +8,13 @@ use crate::{ }, GameSystemSet, }; - -use crate::util::single_mut; use crate::{ - level_instantiation::on_spawn::Player, util::math_trait_ext::Vec3Ext, + level_instantiation::on_spawn::Player, util::Vec3Ext, world_interaction::dialog::CurrentDialogTarget, }; use anyhow::Context; use bevy::prelude::*; use bevy_kira_audio::AudioInstance; -use bevy_mod_sysfail::prelude::*; use bevy_tnua::{builtins::TnuaBuiltinWalk, controller::TnuaController}; use leafwing_input_manager::prelude::ActionState; @@ -31,7 +29,7 @@ pub(super) fn plugin(app: &mut App) { handle_jump, handle_horizontal_movement, rotate_to_speaker, - control_walking_sound, + control_walking_sound.pipe(error), handle_camera_kind, ) .chain() @@ -47,16 +45,13 @@ fn handle_jump(mut player_query: Query<(&ActionState, &mut Jump), } } -#[sysfail(Log)] fn handle_horizontal_movement( mut player_query: Query<(&ActionState, &mut Walk, &mut Sprinting), With>, camera_query: Query<(&IngameCamera, &Transform), Without>, ) { #[cfg(feature = "tracing")] let _span = info_span!("handle_horizontal_movement").entered(); - let Some((camera, camera_transform)) = camera_query.iter().next() else { - return Ok(()); - }; + let (camera, camera_transform) = single!(camera_query); for (actions, mut walk, mut sprint) in &mut player_query { let Some(axis) = actions.axis_pair(&PlayerAction::Move) else { @@ -135,13 +130,12 @@ fn rotate_to_speaker( }); } -#[sysfail(Log)] fn control_walking_sound( time: Res>, character_query: Query<&TnuaController, With>, audio: Res, mut audio_instances: ResMut>, -) { +) -> anyhow::Result<()> { #[cfg(feature = "tracing")] let _span = info_span!("control_walking_sound").entered(); for controller in character_query.iter() { @@ -159,4 +153,5 @@ fn control_walking_sound( audio_instance.pause(default()); } } + Ok(()) } diff --git a/src/util.rs b/src/util.rs index 5cc96f54..2b72bfda 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,8 @@ -pub(crate) mod criteria; -pub(crate) mod math_trait_ext; +mod criteria; +mod math_trait_ext; +mod pipe; + +pub(crate) use self::{criteria::*, math_trait_ext::*, pipe::*}; macro_rules! single { ($query:expr) => { diff --git a/src/util/pipe.rs b/src/util/pipe.rs new file mode 100644 index 00000000..5c2a014e --- /dev/null +++ b/src/util/pipe.rs @@ -0,0 +1,8 @@ +use bevy::log::error; +use bevy::prelude::*; + +pub(crate) fn error(In(result): In>) { + if let Err(err) = result { + error!("Error: {err:?}") + } +} diff --git a/src/world_interaction/interaction_ui.rs b/src/world_interaction/interaction_ui.rs index f6a1fb25..24f21f10 100644 --- a/src/world_interaction/interaction_ui.rs +++ b/src/world_interaction/interaction_ui.rs @@ -6,7 +6,7 @@ use crate::{ actions::{ActionsFrozen, PlayerAction}, camera::{IngameCamera, IngameCameraKind}, }, - util::criteria::is_frozen, + util::is_frozen, world_interaction::dialog::{CurrentDialogTarget, YarnNode}, }; use bevy::{prelude::*, window::PrimaryWindow}; From bd438c111aaafc3b25287ed4d50e2335ace959ea Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 19:02:05 +0200 Subject: [PATCH 6/7] Use newest fast config --- .cargo/config_fast_builds.toml | 145 ++++++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 20 deletions(-) diff --git a/.cargo/config_fast_builds.toml b/.cargo/config_fast_builds.toml index b57e5dc6..20f1bfc0 100644 --- a/.cargo/config_fast_builds.toml +++ b/.cargo/config_fast_builds.toml @@ -1,40 +1,145 @@ -# Add the contents of this file to `config.toml` to enable "fast build" configuration. Please read the notes below. - -# NOTE: For maximum performance, build using a nightly compiler -# If you are using rust stable, remove the "-Zshare-generics=y" below. +# Copy this file to `config.toml` to speed up your builds. +# +# # Faster linker +# +# One of the slowest aspects of compiling large Rust programs is the linking time. This file configures an +# alternate linker that may improve build times. When choosing a new linker, you have two options: +# +# ## LLD +# +# LLD is a linker from the LLVM project that supports Linux, Windows, MacOS, and WASM. It has the greatest +# platform support and the easiest installation process. It is enabled by default in this file for Linux +# and Windows. On MacOS, the default linker yields higher performance than LLD and is used instead. +# +# To install, please scroll to the corresponding table for your target (eg. `[target.x86_64-pc-windows-msvc]` +# for Windows) and follow the steps under `LLD linker`. +# +# For more information, please see LLD's website at . +# +# ## Mold +# +# Mold is a newer linker written by one of the authors of LLD. It boasts even greater performance, specifically +# through its high parallelism, though it only supports Linux. +# +# Mold is disabled by default in this file. If you wish to enable it, follow the installation instructions for +# your corresponding target, disable LLD by commenting out its `-Clink-arg=...` line, and enable Mold by +# *uncommenting* its `-Clink-arg=...` line. +# +# There is a fork of Mold named Sold that supports MacOS, but it is unmaintained and is about the same speed as +# the default ld64 linker. For this reason, it is not included in this file. +# +# For more information, please see Mold's repository at . +# +# # Nightly configuration +# +# Be warned that the following features require nightly Rust, which is expiremental and may contain bugs. If you +# are having issues, skip this section and use stable Rust instead. +# +# There are a few unstable features that can improve performance. To use them, first install nightly Rust +# through Rustup: +# +# ``` +# rustup toolchain install nightly +# ``` +# +# Finally, uncomment the lines under the `Nightly` heading for your corresponding target table (eg. +# `[target.x86_64-unknown-linux-gnu]` for Linux) to enable the following features: +# +# ## `share-generics` +# +# Usually rustc builds each crate separately, then combines them all together at the end. `share-generics` forces +# crates to share monomorphized generic code, so they do not duplicate work. +# +# In other words, instead of crate 1 generating `Foo` and crate 2 generating `Foo` separately, +# only one crate generates `Foo` and the other adds on to the pre-exiting work. +# +# Note that you may have some issues with this flag on Windows. If compiling fails due to the 65k symbol limit, +# you may have to disable this setting. For more information and possible solutions to this error, see +# . +# +# ## `threads` +# +# This option enables rustc's parallel frontend, which improves performance when parsing, type checking, borrow +# checking, and more. We currently set `threads=0`, which defaults to the amount of cores in your CPU. +# +# For more information, see the blog post at . [target.x86_64-unknown-linux-gnu] linker = "clang" rustflags = [ - "-Clink-arg=-fuse-ld=lld", # Use LLD Linker - "-Zshare-generics=y", # (Nightly) Make the current crate share its generic instantiations - "-Zthreads=0", # (Nightly) Use improved multithreading with the recommended amount of threads. + # LLD linker + # + # You may need to install it: + # + # - Ubuntu: `sudo apt-get install lld clang` + # - Fedora: `sudo dnf install lld clang` + # - Arch: `sudo pacman -S lld clang` + "-Clink-arg=-fuse-ld=lld", + # Mold linker + # + # You may need to install it: + # + # - Ubuntu: `sudo apt-get install mold clang` + # - Fedora: `sudo dnf install mold clang` + # - Arch: `sudo pacman -S mold clang` + # "-Clink-arg=-fuse-ld=/usr/bin/mold", + + # Nightly + # "-Zshare-generics=y", + # "-Zthreads=0", ] -# NOTE: you must install [Mach-O LLD Port](https://lld.llvm.org/MachO/index.html) on mac. you can easily do this by installing llvm which includes lld with the "brew" package manager: -# `brew install llvm` [target.x86_64-apple-darwin] rustflags = [ - "-Clink-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld", # Use LLD Linker - "-Zshare-generics=y", # (Nightly) Make the current crate share its generic instantiations - "-Zthreads=0", # (Nightly) Use improved multithreading with the recommended amount of threads. + # LLD linker + # + # The default ld64 linker is faster, you should continue using it instead. + # + # You may need to install it: + # + # Brew: `brew install llvm` + # Manually: + # "-Clink-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld", + + # Nightly + # "-Zshare-generics=y", + # "-Zthreads=0", ] [target.aarch64-apple-darwin] rustflags = [ - "-Clink-arg=-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld", # Use LLD Linker - "-Zshare-generics=y", # (Nightly) Make the current crate share its generic instantiations - "-Zthreads=0", # (Nightly) Use improved multithreading with the recommended amount of threads. + # LLD linker + # + # The default ld64 linker is faster, you should continue using it instead. + # + # You may need to install it: + # + # Brew: `brew install llvm` + # Manually: + # "-Clink-arg=-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld", + + # Nightly + # "-Zshare-generics=y", + # "-Zthreads=0", ] [target.x86_64-pc-windows-msvc] -linker = "rust-lld.exe" # Use LLD Linker +# LLD linker +# +# You may need to install it: +# +# ``` +# cargo install -f cargo-binutils +# rustup component add llvm-tools +# ``` +linker = "rust-lld.exe" rustflags = [ - "-Zshare-generics=n", - "-Zthreads=0", # (Nightly) Use improved multithreading with the recommended amount of threads. + # Nightly + # "-Zshare-generics=y", + # "-Zthreads=0", ] # Optional: Uncommenting the following improves compile times, but reduces the amount of debug info to 'line number tables only' # In most cases the gains are negligible, but if you are on macos and have slow compile times you should see significant gains. -#[profile.dev] -#debug = 1 +# [profile.dev] +# debug = 1 From 3e6061d8677408d1ac058df0f8ee15758740dc3a Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Thu, 27 Jun 2024 19:04:11 +0200 Subject: [PATCH 7/7] Move some things in the readme --- readme.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 97b6b510..f256a5db 100644 --- a/readme.md +++ b/readme.md @@ -6,22 +6,21 @@ https://user-images.githubusercontent.com/9047632/226387411-70f662de-0681-47ff-b ## What does this template give you? -- A 3D character controller via [`bevy-tnua`](https://crates.io/crates/bevy-tnua) +- Integration with Blender as an editor via + the [`Blender_bevy_components_workflow`](https://github.com/kaosat-dev/Blender_bevy_components_workflow) set of tools - Physics via [`bevy_xpbd`](https://crates.io/crates/bevy_xpbd_3d) + - A 3D character controller via [`bevy-tnua`](https://crates.io/crates/bevy-tnua) - Audio via [`bevy_kira_audio`](https://crates.io/crates/bevy_kira_audio) - Pathfinding via [`oxidized_navigation`](https://crates.io/crates/oxidized_navigation) - [`bevy_editor_pls`](https://crates.io/crates/bevy_editor_pls) bound to 'Q' -- Custom editor found in the windows selection for `bevy_editor_pls`. + - Custom editor found in the windows selection for `bevy_editor_pls`. - Animations - Dialogs via [`Yarn Spinner for Rust`](https://crates.io/crates/bevy_yarnspinner) - Shaders, using the code from [DGriffin's tutorial](https://www.youtube.com/watch?v=O6A_nVmpvhc) -- GLTF imports, including auto-insertion of markers via the GLTF extras field - Smooth cameras via [`bevy_dolly`](https://crates.io/crates/bevy_dolly) - Particle effects via [`bevy_hanabi`](https://crates.io/crates/bevy_hanabi) - Procedural skies via [`bevy_atmosphere`](https://crates.io/crates/bevy_atmosphere) - Grass via [`warbler_grass`](https://crates.io/crates/warbler_grass) -- Integration with Blender as an editor via - the [`Blender_bevy_components_workflow`](https://github.com/kaosat-dev/Blender_bevy_components_workflow) set of tools ## Usage