From ed2c57a3bb2916c06e2c6ccc6607c4e77251c267 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 19:17:35 +0100 Subject: [PATCH 01/21] fps overlay --- crates/bevy_dev_tools/Cargo.toml | 4 ++ crates/bevy_dev_tools/src/fps_overlay.rs | 53 ++++++++++++++++++++++++ crates/bevy_dev_tools/src/lib.rs | 2 + 3 files changed, 59 insertions(+) create mode 100644 crates/bevy_dev_tools/src/fps_overlay.rs diff --git a/crates/bevy_dev_tools/Cargo.toml b/crates/bevy_dev_tools/Cargo.toml index 18f66b4e5a3aa..f5d11e138e712 100644 --- a/crates/bevy_dev_tools/Cargo.toml +++ b/crates/bevy_dev_tools/Cargo.toml @@ -19,6 +19,10 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_render = { path = "../bevy_render", version = "0.14.0-dev" } bevy_time = { path = "../bevy_time", version = "0.14.0-dev" } bevy_window = { path = "../bevy_window", version = "0.14.0-dev" } +bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } +bevy_ui = { path = "../bevy_ui", version = "0.14.0-dev" } +bevy_text = { path = "../bevy_text", version = "0.14.0-dev" } +bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.14.0-dev" } # other serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs new file mode 100644 index 0000000000000..5ac2c8673669a --- /dev/null +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -0,0 +1,53 @@ +use bevy_app::{Plugin, Startup, Update}; +use bevy_diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}; +use bevy_ecs::{ + component::Component, + query::With, + system::{Commands, Query, Res}, +}; +use bevy_text::{Text, TextSection, TextStyle}; +use bevy_ui::node_bundles::TextBundle; + +pub struct FpsOverlayPlugin; + +impl Plugin for FpsOverlayPlugin { + fn build(&self, app: &mut bevy_app::App) { + if !app.is_plugin_added::() { + app.add_plugins(FrameTimeDiagnosticsPlugin); + } + app.add_systems(Startup, setup) + .add_systems(Update, update_text); + } +} + +#[derive(Component)] +struct FpsText; + +fn setup(mut commands: Commands) { + commands.spawn(( + TextBundle::from_sections([ + TextSection::new( + "FPS: ", + TextStyle { + font_size: 32.0, + ..Default::default() + }, + ), + TextSection::from_style(TextStyle { + font_size: 32.0, + ..Default::default() + }), + ]), + FpsText, + )); +} + +fn update_text(diagnostic: Res, mut query: Query<&mut Text, With>) { + for mut text in &mut query { + if let Some(fps) = diagnostic.get(&FrameTimeDiagnosticsPlugin::FPS) { + if let Some(value) = fps.smoothed() { + text.sections[1].value = format!("{value:.2}"); + } + } + } +} diff --git a/crates/bevy_dev_tools/src/lib.rs b/crates/bevy_dev_tools/src/lib.rs index b025539ebbb57..9b38c99817968 100644 --- a/crates/bevy_dev_tools/src/lib.rs +++ b/crates/bevy_dev_tools/src/lib.rs @@ -2,8 +2,10 @@ //! focused on improving developer experience. use bevy_app::prelude::*; + #[cfg(feature = "bevy_ci_testing")] pub mod ci_testing; +pub mod fps_overlay; /// Enables developer tools in an [`App`]. This plugin is added automatically with `bevy_dev_tools` /// feature. From 4a3ffe9f83faa8781a73f42aea79356d59998465 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 20:11:29 +0100 Subject: [PATCH 02/21] add config for overlay --- crates/bevy_dev_tools/Cargo.toml | 1 + crates/bevy_dev_tools/src/fps_overlay.rs | 96 +++++++++++++++++++++--- 2 files changed, 86 insertions(+), 11 deletions(-) diff --git a/crates/bevy_dev_tools/Cargo.toml b/crates/bevy_dev_tools/Cargo.toml index f5d11e138e712..28f259fa6f154 100644 --- a/crates/bevy_dev_tools/Cargo.toml +++ b/crates/bevy_dev_tools/Cargo.toml @@ -23,6 +23,7 @@ bevy_asset = { path = "../bevy_asset", version = "0.14.0-dev" } bevy_ui = { path = "../bevy_ui", version = "0.14.0-dev" } bevy_text = { path = "../bevy_text", version = "0.14.0-dev" } bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.14.0-dev" } +bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } # other serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 5ac2c8673669a..dca7a2f7cef15 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -1,41 +1,87 @@ use bevy_app::{Plugin, Startup, Update}; +use bevy_asset::AssetServer; +use bevy_color::Color; use bevy_diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}; use bevy_ecs::{ + change_detection::DetectChanges, component::Component, query::With, - system::{Commands, Query, Res}, + system::{Commands, Query, Res, Resource}, }; use bevy_text::{Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; -pub struct FpsOverlayPlugin; +#[derive(Default)] +pub struct FpsOverlayPlugin { + pub config: FpsOverlayConfig, +} impl Plugin for FpsOverlayPlugin { fn build(&self, app: &mut bevy_app::App) { if !app.is_plugin_added::() { app.add_plugins(FrameTimeDiagnosticsPlugin); } - app.add_systems(Startup, setup) - .add_systems(Update, update_text); + app.insert_resource(self.config.clone()) + .add_systems(Startup, setup) + .add_systems(Update, (customize_text, update_text)); + } +} + +#[derive(Resource, Clone)] +pub struct FpsOverlayConfig { + pub font_path: Option, + pub font_size: f32, + pub font_color: Color, +} + +impl Default for FpsOverlayConfig { + fn default() -> Self { + FpsOverlayConfig { + font_path: None, + font_size: 32.0, + font_color: Color::WHITE, + } } } #[derive(Component)] struct FpsText; -fn setup(mut commands: Commands) { +fn setup( + mut commands: Commands, + overlay_config: Res, + asset_server: Res, +) { commands.spawn(( TextBundle::from_sections([ TextSection::new( "FPS: ", - TextStyle { - font_size: 32.0, - ..Default::default() + if let Some(font_path) = &overlay_config.font_path { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + font: asset_server.load(font_path), + } + } else { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + ..Default::default() + } }, ), - TextSection::from_style(TextStyle { - font_size: 32.0, - ..Default::default() + TextSection::from_style(if let Some(font_path) = &overlay_config.font_path { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + font: asset_server.load(font_path), + } + } else { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + ..Default::default() + } }), ]), FpsText, @@ -51,3 +97,31 @@ fn update_text(diagnostic: Res, mut query: Query<&mut Text, Wi } } } + +fn customize_text( + overlay_config: Res, + asset_server: Res, + mut query: Query<&mut Text, With>, +) { + if !overlay_config.is_changed() { + return; + } + + for mut text in &mut query { + for section in text.sections.iter_mut() { + section.style = if let Some(font_path) = &overlay_config.font_path { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + font: asset_server.load(font_path), + } + } else { + TextStyle { + font_size: overlay_config.font_size, + color: overlay_config.font_color, + ..Default::default() + } + } + } + } +} From 0cdfe3778260f98754ca187dbc0256554f85ffcd Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 21:36:20 +0100 Subject: [PATCH 03/21] add toggle to overlay --- crates/bevy_dev_tools/Cargo.toml | 1 + crates/bevy_dev_tools/src/fps_overlay.rs | 34 +++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/crates/bevy_dev_tools/Cargo.toml b/crates/bevy_dev_tools/Cargo.toml index 28f259fa6f154..9d7e23a0ec1db 100644 --- a/crates/bevy_dev_tools/Cargo.toml +++ b/crates/bevy_dev_tools/Cargo.toml @@ -24,6 +24,7 @@ bevy_ui = { path = "../bevy_ui", version = "0.14.0-dev" } bevy_text = { path = "../bevy_text", version = "0.14.0-dev" } bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.14.0-dev" } bevy_color = { path = "../bevy_color", version = "0.14.0-dev" } +bevy_input = { path = "../bevy_input", version = "0.14.0-dev" } # other serde = { version = "1.0", features = ["derive"], optional = true } diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index dca7a2f7cef15..b6f0266967381 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -8,6 +8,8 @@ use bevy_ecs::{ query::With, system::{Commands, Query, Res, Resource}, }; +use bevy_input::{keyboard::KeyCode, ButtonInput}; +use bevy_render::view::Visibility; use bevy_text::{Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; @@ -23,7 +25,7 @@ impl Plugin for FpsOverlayPlugin { } app.insert_resource(self.config.clone()) .add_systems(Startup, setup) - .add_systems(Update, (customize_text, update_text)); + .add_systems(Update, (customize_text, update_text, toggle_overlay)); } } @@ -32,6 +34,7 @@ pub struct FpsOverlayConfig { pub font_path: Option, pub font_size: f32, pub font_color: Color, + pub keybind: Option, } impl Default for FpsOverlayConfig { @@ -40,6 +43,7 @@ impl Default for FpsOverlayConfig { font_path: None, font_size: 32.0, font_color: Color::WHITE, + keybind: None, } } } @@ -88,8 +92,14 @@ fn setup( )); } -fn update_text(diagnostic: Res, mut query: Query<&mut Text, With>) { - for mut text in &mut query { +fn update_text( + diagnostic: Res, + mut query: Query<(&mut Text, &Visibility), With>, +) { + for (mut text, visibility) in &mut query { + if let Visibility::Hidden = *visibility { + return; + } if let Some(fps) = diagnostic.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(value) = fps.smoothed() { text.sections[1].value = format!("{value:.2}"); @@ -125,3 +135,21 @@ fn customize_text( } } } + +fn toggle_overlay( + input: Res>, + mut query: Query<&mut Visibility, With>, + overlay_config: Res, +) { + if (overlay_config.keybind.is_none() && input.just_pressed(KeyCode::F1)) + | (overlay_config.keybind.is_some() && input.just_pressed(overlay_config.keybind.unwrap())) + { + for mut visibility in query.iter_mut() { + *visibility = if let Visibility::Hidden = *visibility { + Visibility::Visible + } else { + Visibility::Hidden + } + } + } +} From 7fe771d06849376b6a5083f9454d41831ecbe596 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 21:52:20 +0100 Subject: [PATCH 04/21] basic docs --- crates/bevy_dev_tools/src/fps_overlay.rs | 9 +++++++++ crates/bevy_dev_tools/src/lib.rs | 1 + 2 files changed, 10 insertions(+) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index b6f0266967381..f5d78b0d7b159 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -14,7 +14,9 @@ use bevy_text::{Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; #[derive(Default)] +/// A plugin that adds an FPS overlay to the Bevy application. pub struct FpsOverlayPlugin { + /// Starting configuration of overlay, this can be later be changed through `[FpsOverlayConfig]` resource. pub config: FpsOverlayConfig, } @@ -30,10 +32,17 @@ impl Plugin for FpsOverlayPlugin { } #[derive(Resource, Clone)] +/// Configuration options for the FPS overlay. pub struct FpsOverlayConfig { + /// File path for the font file. If set to `None`,the default font is used. + /// Note: The overlay won't be visible if you set it to `None` and run without `default_font` feature. pub font_path: Option, + /// Size of the overlay text. pub font_size: f32, + /// Color of the overlay text. pub font_color: Color, + /// Keybind for toggling on/off the overlay. + /// If set to none, [`KeyCode::F1`] is used pub keybind: Option, } diff --git a/crates/bevy_dev_tools/src/lib.rs b/crates/bevy_dev_tools/src/lib.rs index 9b38c99817968..7a5f41dde1a57 100644 --- a/crates/bevy_dev_tools/src/lib.rs +++ b/crates/bevy_dev_tools/src/lib.rs @@ -5,6 +5,7 @@ use bevy_app::prelude::*; #[cfg(feature = "bevy_ci_testing")] pub mod ci_testing; +/// Module containing logic for FPS overlay. pub mod fps_overlay; /// Enables developer tools in an [`App`]. This plugin is added automatically with `bevy_dev_tools` From fe69f27399ea6a6cc6ba56e33ab9b7f4afdbb478 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 23:13:16 +0100 Subject: [PATCH 05/21] add example --- Cargo.toml | 12 ++++++ examples/README.md | 7 ++++ examples/dev_tools/fps_overlay.rs | 65 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 examples/dev_tools/fps_overlay.rs diff --git a/Cargo.toml b/Cargo.toml index 4f365f59f2ede..2ee18a147baf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2763,6 +2763,18 @@ description = "A scene showcasing light gizmos" category = "Gizmos" wasm = true +[[example]] +name = "fps_overlay" +path = "examples/dev_tools/fps_overlay.rs" +doc-scrape-examples = true +required-features = ["bevy_dev_tools"] + +[package.metadata.example.fps_overlay] +name = "FPS overlay" +description = "Demonstrates FPS overlay" +category = "Dev tools" +wasm = true + [profile.wasm-release] inherits = "release" opt-level = "z" diff --git a/examples/README.md b/examples/README.md index c7e19f1e06323..47c59cb9069d0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -45,6 +45,7 @@ git checkout v0.4.0 - [Assets](#assets) - [Async Tasks](#async-tasks) - [Audio](#audio) + - [Dev tools](#dev-tools) - [Diagnostics](#diagnostics) - [ECS (Entity Component System)](#ecs-entity-component-system) - [Games](#games) @@ -219,6 +220,12 @@ Example | Description [Spatial Audio 2D](../examples/audio/spatial_audio_2d.rs) | Shows how to play spatial audio, and moving the emitter in 2D [Spatial Audio 3D](../examples/audio/spatial_audio_3d.rs) | Shows how to play spatial audio, and moving the emitter in 3D +## Dev tools + +Example | Description +--- | --- +[FPS overlay](../examples/dev_tools/fps_overlay.rs) | Demonstrates FPS overlay + ## Diagnostics Example | Description diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs new file mode 100644 index 0000000000000..1c48ffde17373 --- /dev/null +++ b/examples/dev_tools/fps_overlay.rs @@ -0,0 +1,65 @@ +//! Showcase how to use and configure FPS overlay. + +use bevy::{ + dev_tools::fps_overlay::{FpsOverlayConfig, FpsOverlayPlugin}, + prelude::*, +}; + +fn main() { + App::new() + .add_plugins(( + DefaultPlugins, + FpsOverlayPlugin { + config: FpsOverlayConfig { + // Here we define size of our overlay + font_size: 50.0, + // We can also change color of the overlay + font_color: Color::srgb(0.0, 1.0, 0.0), + // If we want, we can use a custom font + font_path: None, + // This keybind will be toggling on/off the overlay + keybind: Some(KeyCode::Escape), + }, + }, + )) + .add_systems(Startup, setup) + .add_systems(Update, system) + .run(); +} + +fn setup(mut commands: Commands) { + // We need to spawn camera to see overlay + commands.spawn(Camera2dBundle::default()); + commands.spawn( + TextBundle::from_sections([ + TextSection::new( + "Press 1 to change color of the overlay.", + TextStyle { + font_size: 25.0, + ..default() + }, + ), + TextSection::new( + "\nPress 2 to change size of the overlay", + TextStyle { + font_size: 25.0, + ..default() + }, + ), + ]) + .with_style(Style { + justify_self: JustifySelf::Center, + ..default() + }), + ); +} + +fn system(input: Res>, mut overlay: ResMut) { + if input.just_pressed(KeyCode::Digit1) { + // Changing resource will affect overlay + overlay.font_color = Color::srgb(1.0, 0.0, 0.0); + } + if input.just_pressed(KeyCode::Digit2) { + overlay.font_size -= 2.0; + } +} From e237531f62d0d98b649ac45d3d3a86626d0db780 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 23:28:16 +0100 Subject: [PATCH 06/21] use KeyCode instead of Option for keybind --- crates/bevy_dev_tools/src/fps_overlay.rs | 9 +++------ examples/dev_tools/fps_overlay.rs | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index f5d78b0d7b159..d7a3aea011164 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -42,8 +42,7 @@ pub struct FpsOverlayConfig { /// Color of the overlay text. pub font_color: Color, /// Keybind for toggling on/off the overlay. - /// If set to none, [`KeyCode::F1`] is used - pub keybind: Option, + pub keybind: KeyCode, } impl Default for FpsOverlayConfig { @@ -52,7 +51,7 @@ impl Default for FpsOverlayConfig { font_path: None, font_size: 32.0, font_color: Color::WHITE, - keybind: None, + keybind: KeyCode::F1, } } } @@ -150,9 +149,7 @@ fn toggle_overlay( mut query: Query<&mut Visibility, With>, overlay_config: Res, ) { - if (overlay_config.keybind.is_none() && input.just_pressed(KeyCode::F1)) - | (overlay_config.keybind.is_some() && input.just_pressed(overlay_config.keybind.unwrap())) - { + if input.just_pressed(overlay_config.keybind) { for mut visibility in query.iter_mut() { *visibility = if let Visibility::Hidden = *visibility { Visibility::Visible diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 1c48ffde17373..7fc299d89496f 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -18,7 +18,7 @@ fn main() { // If we want, we can use a custom font font_path: None, // This keybind will be toggling on/off the overlay - keybind: Some(KeyCode::Escape), + keybind: KeyCode::Escape, }, }, )) From edb1846263ae4afc51037a9e69a143aeb08c8a69 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 23:32:58 +0100 Subject: [PATCH 07/21] use run_if condition --- crates/bevy_dev_tools/src/fps_overlay.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index d7a3aea011164..60dd6be0513f2 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -6,6 +6,7 @@ use bevy_ecs::{ change_detection::DetectChanges, component::Component, query::With, + schedule::{common_conditions::resource_changed, IntoSystemConfigs}, system::{Commands, Query, Res, Resource}, }; use bevy_input::{keyboard::KeyCode, ButtonInput}; @@ -27,7 +28,14 @@ impl Plugin for FpsOverlayPlugin { } app.insert_resource(self.config.clone()) .add_systems(Startup, setup) - .add_systems(Update, (customize_text, update_text, toggle_overlay)); + .add_systems( + Update, + ( + customize_text.run_if(resource_changed::), + update_text, + toggle_overlay, + ), + ); } } @@ -121,10 +129,6 @@ fn customize_text( asset_server: Res, mut query: Query<&mut Text, With>, ) { - if !overlay_config.is_changed() { - return; - } - for mut text in &mut query { for section in text.sections.iter_mut() { section.style = if let Some(font_path) = &overlay_config.font_path { From b05af3754a2c6578e083f760127e722ece0dcf65 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 23:36:07 +0100 Subject: [PATCH 08/21] add text in example about toggling overlay --- examples/dev_tools/fps_overlay.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 7fc299d89496f..1f2c4910c6e44 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -33,7 +33,14 @@ fn setup(mut commands: Commands) { commands.spawn( TextBundle::from_sections([ TextSection::new( - "Press 1 to change color of the overlay.", + "Press ESC to toggle overlay", + TextStyle { + font_size: 25.0, + ..default() + }, + ), + TextSection::new( + "\nPress 1 to change color of the overlay.", TextStyle { font_size: 25.0, ..default() From e0a3bec8aef3ffec687d8ad3befc2b32e0f85093 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Fri, 8 Mar 2024 23:37:37 +0100 Subject: [PATCH 09/21] remove unused import --- crates/bevy_dev_tools/src/fps_overlay.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 60dd6be0513f2..2d4bbfa09ab0a 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -3,7 +3,6 @@ use bevy_asset::AssetServer; use bevy_color::Color; use bevy_diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}; use bevy_ecs::{ - change_detection::DetectChanges, component::Component, query::With, schedule::{common_conditions::resource_changed, IntoSystemConfigs}, From ede91b8a2a6513742bce577fd6947aa646393a29 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 00:11:16 +0100 Subject: [PATCH 10/21] remove toggling overlay --- crates/bevy_dev_tools/src/fps_overlay.rs | 32 ++---------------------- examples/dev_tools/fps_overlay.rs | 11 +------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 2d4bbfa09ab0a..39e375bdae53e 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -8,8 +8,6 @@ use bevy_ecs::{ schedule::{common_conditions::resource_changed, IntoSystemConfigs}, system::{Commands, Query, Res, Resource}, }; -use bevy_input::{keyboard::KeyCode, ButtonInput}; -use bevy_render::view::Visibility; use bevy_text::{Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; @@ -32,7 +30,6 @@ impl Plugin for FpsOverlayPlugin { ( customize_text.run_if(resource_changed::), update_text, - toggle_overlay, ), ); } @@ -48,8 +45,6 @@ pub struct FpsOverlayConfig { pub font_size: f32, /// Color of the overlay text. pub font_color: Color, - /// Keybind for toggling on/off the overlay. - pub keybind: KeyCode, } impl Default for FpsOverlayConfig { @@ -58,7 +53,6 @@ impl Default for FpsOverlayConfig { font_path: None, font_size: 32.0, font_color: Color::WHITE, - keybind: KeyCode::F1, } } } @@ -107,14 +101,8 @@ fn setup( )); } -fn update_text( - diagnostic: Res, - mut query: Query<(&mut Text, &Visibility), With>, -) { - for (mut text, visibility) in &mut query { - if let Visibility::Hidden = *visibility { - return; - } +fn update_text(diagnostic: Res, mut query: Query<&mut Text, With>) { + for mut text in &mut query { if let Some(fps) = diagnostic.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(value) = fps.smoothed() { text.sections[1].value = format!("{value:.2}"); @@ -146,19 +134,3 @@ fn customize_text( } } } - -fn toggle_overlay( - input: Res>, - mut query: Query<&mut Visibility, With>, - overlay_config: Res, -) { - if input.just_pressed(overlay_config.keybind) { - for mut visibility in query.iter_mut() { - *visibility = if let Visibility::Hidden = *visibility { - Visibility::Visible - } else { - Visibility::Hidden - } - } - } -} diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 1f2c4910c6e44..a8c4717724fb4 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -17,8 +17,6 @@ fn main() { font_color: Color::srgb(0.0, 1.0, 0.0), // If we want, we can use a custom font font_path: None, - // This keybind will be toggling on/off the overlay - keybind: KeyCode::Escape, }, }, )) @@ -33,14 +31,7 @@ fn setup(mut commands: Commands) { commands.spawn( TextBundle::from_sections([ TextSection::new( - "Press ESC to toggle overlay", - TextStyle { - font_size: 25.0, - ..default() - }, - ), - TextSection::new( - "\nPress 1 to change color of the overlay.", + "Press 1 to change color of the overlay.", TextStyle { font_size: 25.0, ..default() From 319744df1ac200db90f2853adc445f210fbd0a23 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 13:10:56 +0100 Subject: [PATCH 11/21] take TextStyle as a config --- crates/bevy_dev_tools/src/fps_overlay.rs | 74 ++++-------------------- examples/dev_tools/fps_overlay.rs | 12 ++-- 2 files changed, 17 insertions(+), 69 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 39e375bdae53e..8bf95b363e1dc 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -1,5 +1,5 @@ use bevy_app::{Plugin, Startup, Update}; -use bevy_asset::AssetServer; +use bevy_asset::Handle; use bevy_color::Color; use bevy_diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}; use bevy_ecs::{ @@ -8,7 +8,7 @@ use bevy_ecs::{ schedule::{common_conditions::resource_changed, IntoSystemConfigs}, system::{Commands, Query, Res, Resource}, }; -use bevy_text::{Text, TextSection, TextStyle}; +use bevy_text::{Font, Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; #[derive(Default)] @@ -37,65 +37,26 @@ impl Plugin for FpsOverlayPlugin { #[derive(Resource, Clone)] /// Configuration options for the FPS overlay. -pub struct FpsOverlayConfig { - /// File path for the font file. If set to `None`,the default font is used. - /// Note: The overlay won't be visible if you set it to `None` and run without `default_font` feature. - pub font_path: Option, - /// Size of the overlay text. - pub font_size: f32, - /// Color of the overlay text. - pub font_color: Color, -} +pub struct FpsOverlayConfig(pub TextStyle); impl Default for FpsOverlayConfig { fn default() -> Self { - FpsOverlayConfig { - font_path: None, + FpsOverlayConfig(TextStyle { + font: Handle::::default(), font_size: 32.0, - font_color: Color::WHITE, - } + color: Color::WHITE, + }) } } #[derive(Component)] struct FpsText; -fn setup( - mut commands: Commands, - overlay_config: Res, - asset_server: Res, -) { +fn setup(mut commands: Commands, overlay_config: Res) { commands.spawn(( TextBundle::from_sections([ - TextSection::new( - "FPS: ", - if let Some(font_path) = &overlay_config.font_path { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - font: asset_server.load(font_path), - } - } else { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - ..Default::default() - } - }, - ), - TextSection::from_style(if let Some(font_path) = &overlay_config.font_path { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - font: asset_server.load(font_path), - } - } else { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - ..Default::default() - } - }), + TextSection::new("FPS: ", overlay_config.0.clone()), + TextSection::from_style(overlay_config.0.clone()), ]), FpsText, )); @@ -113,24 +74,11 @@ fn update_text(diagnostic: Res, mut query: Query<&mut Text, Wi fn customize_text( overlay_config: Res, - asset_server: Res, mut query: Query<&mut Text, With>, ) { for mut text in &mut query { for section in text.sections.iter_mut() { - section.style = if let Some(font_path) = &overlay_config.font_path { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - font: asset_server.load(font_path), - } - } else { - TextStyle { - font_size: overlay_config.font_size, - color: overlay_config.font_color, - ..Default::default() - } - } + section.style = overlay_config.0.clone(); } } } diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index a8c4717724fb4..94fd984764644 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -10,14 +10,14 @@ fn main() { .add_plugins(( DefaultPlugins, FpsOverlayPlugin { - config: FpsOverlayConfig { + config: FpsOverlayConfig(TextStyle { // Here we define size of our overlay font_size: 50.0, // We can also change color of the overlay - font_color: Color::srgb(0.0, 1.0, 0.0), + color: Color::srgb(0.0, 1.0, 0.0), // If we want, we can use a custom font - font_path: None, - }, + font: default(), + }), }, )) .add_systems(Startup, setup) @@ -55,9 +55,9 @@ fn setup(mut commands: Commands) { fn system(input: Res>, mut overlay: ResMut) { if input.just_pressed(KeyCode::Digit1) { // Changing resource will affect overlay - overlay.font_color = Color::srgb(1.0, 0.0, 0.0); + overlay.0.color = Color::srgb(1.0, 0.0, 0.0); } if input.just_pressed(KeyCode::Digit2) { - overlay.font_size -= 2.0; + overlay.0.font_size -= 2.0; } } From 4dba1aaee4f69ba762e0d4742848decaaa7a86ac Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 13:14:04 +0100 Subject: [PATCH 12/21] rename system in fps_overlay example --- examples/dev_tools/fps_overlay.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 94fd984764644..9658ad967f245 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -21,7 +21,7 @@ fn main() { }, )) .add_systems(Startup, setup) - .add_systems(Update, system) + .add_systems(Update, customize_config) .run(); } @@ -52,7 +52,7 @@ fn setup(mut commands: Commands) { ); } -fn system(input: Res>, mut overlay: ResMut) { +fn customize_config(input: Res>, mut overlay: ResMut) { if input.just_pressed(KeyCode::Digit1) { // Changing resource will affect overlay overlay.0.color = Color::srgb(1.0, 0.0, 0.0); From 140433f8f7ab71376404e49a8a47761e733f4e62 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 13:16:34 +0100 Subject: [PATCH 13/21] add warning to FpsOverlayPlugin --- crates/bevy_dev_tools/src/fps_overlay.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 8bf95b363e1dc..da08d774c2ec0 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -13,6 +13,7 @@ use bevy_ui::node_bundles::TextBundle; #[derive(Default)] /// A plugin that adds an FPS overlay to the Bevy application. +/// Warning: This plugin will add [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. pub struct FpsOverlayPlugin { /// Starting configuration of overlay, this can be later be changed through `[FpsOverlayConfig]` resource. pub config: FpsOverlayConfig, From 75a97df1684a8a64ec7e7a2a108ca935daba8015 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 13:16:52 +0100 Subject: [PATCH 14/21] fix doc link --- crates/bevy_dev_tools/src/fps_overlay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index da08d774c2ec0..544a347bad10c 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -15,7 +15,7 @@ use bevy_ui::node_bundles::TextBundle; /// A plugin that adds an FPS overlay to the Bevy application. /// Warning: This plugin will add [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. pub struct FpsOverlayPlugin { - /// Starting configuration of overlay, this can be later be changed through `[FpsOverlayConfig]` resource. + /// Starting configuration of overlay, this can be later be changed through [`FpsOverlayConfig`] resource. pub config: FpsOverlayConfig, } From c5a733d95e0d4faf95e62cc67d59e11a791c1248 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 14:19:31 +0100 Subject: [PATCH 15/21] add docs about native overlay --- crates/bevy_dev_tools/src/fps_overlay.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 544a347bad10c..8aab7da7b1cd7 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -14,6 +14,10 @@ use bevy_ui::node_bundles::TextBundle; #[derive(Default)] /// A plugin that adds an FPS overlay to the Bevy application. /// Warning: This plugin will add [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. +/// +/// Note: It is recommended to use native overlay of the rendering APi when possible. You can do +/// this by: +/// - **Metal**: setting env variable `MTL_HUD_ENABLED=1` pub struct FpsOverlayPlugin { /// Starting configuration of overlay, this can be later be changed through [`FpsOverlayConfig`] resource. pub config: FpsOverlayConfig, From db9c98c47090b06ced211fc391c37c838f60dc1f Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 14:23:46 +0100 Subject: [PATCH 16/21] fix doc --- crates/bevy_dev_tools/src/fps_overlay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 8aab7da7b1cd7..8f6d88652d2a6 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -15,7 +15,7 @@ use bevy_ui::node_bundles::TextBundle; /// A plugin that adds an FPS overlay to the Bevy application. /// Warning: This plugin will add [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. /// -/// Note: It is recommended to use native overlay of the rendering APi when possible. You can do +/// Note: It is recommended to use native overlay of the rendering `API` when possible. You can do /// this by: /// - **Metal**: setting env variable `MTL_HUD_ENABLED=1` pub struct FpsOverlayPlugin { From b2718b4b4e9ce6b3d7552b9fa7b9bd7ffb315bf4 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 18:15:57 +0100 Subject: [PATCH 17/21] improve docs Co-authored-by: Alice Cecile --- crates/bevy_dev_tools/src/fps_overlay.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 8f6d88652d2a6..27269e409ca78 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -13,10 +13,11 @@ use bevy_ui::node_bundles::TextBundle; #[derive(Default)] /// A plugin that adds an FPS overlay to the Bevy application. -/// Warning: This plugin will add [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. /// -/// Note: It is recommended to use native overlay of the rendering `API` when possible. You can do -/// this by: +/// This plugin will add the [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. +/// +/// Note: It is recommended to use native overlay of rendering statistics when possible for lower overhead and more accurate results. +/// The correct way to do this will vary by platform: /// - **Metal**: setting env variable `MTL_HUD_ENABLED=1` pub struct FpsOverlayPlugin { /// Starting configuration of overlay, this can be later be changed through [`FpsOverlayConfig`] resource. From 4b380d86179cc405d6329b55f0494d4712a06ec6 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 18:22:36 +0100 Subject: [PATCH 18/21] move derive attribute --- crates/bevy_dev_tools/src/fps_overlay.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 27269e409ca78..afca3b4ce4933 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -11,7 +11,6 @@ use bevy_ecs::{ use bevy_text::{Font, Text, TextSection, TextStyle}; use bevy_ui::node_bundles::TextBundle; -#[derive(Default)] /// A plugin that adds an FPS overlay to the Bevy application. /// /// This plugin will add the [`FrameTimeDiagnosticsPlugin`] if it wasn't added before. @@ -19,6 +18,7 @@ use bevy_ui::node_bundles::TextBundle; /// Note: It is recommended to use native overlay of rendering statistics when possible for lower overhead and more accurate results. /// The correct way to do this will vary by platform: /// - **Metal**: setting env variable `MTL_HUD_ENABLED=1` +#[derive(Default)] pub struct FpsOverlayPlugin { /// Starting configuration of overlay, this can be later be changed through [`FpsOverlayConfig`] resource. pub config: FpsOverlayConfig, @@ -41,8 +41,8 @@ impl Plugin for FpsOverlayPlugin { } } -#[derive(Resource, Clone)] /// Configuration options for the FPS overlay. +#[derive(Resource, Clone)] pub struct FpsOverlayConfig(pub TextStyle); impl Default for FpsOverlayConfig { From a6bd2db0fc5acf530abbf7a487ddfcc2b29ea536 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 18:26:45 +0100 Subject: [PATCH 19/21] use named fields in FpsOverlayConfig --- crates/bevy_dev_tools/src/fps_overlay.rs | 23 ++++++++++++++--------- examples/dev_tools/fps_overlay.rs | 22 ++++++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index afca3b4ce4933..5e5d9546384dd 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -43,15 +43,20 @@ impl Plugin for FpsOverlayPlugin { /// Configuration options for the FPS overlay. #[derive(Resource, Clone)] -pub struct FpsOverlayConfig(pub TextStyle); +pub struct FpsOverlayConfig { + /// Configuration of text in the overlay. + pub text_config: TextStyle, +} impl Default for FpsOverlayConfig { fn default() -> Self { - FpsOverlayConfig(TextStyle { - font: Handle::::default(), - font_size: 32.0, - color: Color::WHITE, - }) + FpsOverlayConfig { + text_config: TextStyle { + font: Handle::::default(), + font_size: 32.0, + color: Color::WHITE, + }, + } } } @@ -61,8 +66,8 @@ struct FpsText; fn setup(mut commands: Commands, overlay_config: Res) { commands.spawn(( TextBundle::from_sections([ - TextSection::new("FPS: ", overlay_config.0.clone()), - TextSection::from_style(overlay_config.0.clone()), + TextSection::new("FPS: ", overlay_config.text_config.clone()), + TextSection::from_style(overlay_config.text_config.clone()), ]), FpsText, )); @@ -84,7 +89,7 @@ fn customize_text( ) { for mut text in &mut query { for section in text.sections.iter_mut() { - section.style = overlay_config.0.clone(); + section.style = overlay_config.text_config.clone(); } } } diff --git a/examples/dev_tools/fps_overlay.rs b/examples/dev_tools/fps_overlay.rs index 9658ad967f245..e7f4cada95462 100644 --- a/examples/dev_tools/fps_overlay.rs +++ b/examples/dev_tools/fps_overlay.rs @@ -10,14 +10,16 @@ fn main() { .add_plugins(( DefaultPlugins, FpsOverlayPlugin { - config: FpsOverlayConfig(TextStyle { - // Here we define size of our overlay - font_size: 50.0, - // We can also change color of the overlay - color: Color::srgb(0.0, 1.0, 0.0), - // If we want, we can use a custom font - font: default(), - }), + config: FpsOverlayConfig { + text_config: TextStyle { + // Here we define size of our overlay + font_size: 50.0, + // We can also change color of the overlay + color: Color::srgb(0.0, 1.0, 0.0), + // If we want, we can use a custom font + font: default(), + }, + }, }, )) .add_systems(Startup, setup) @@ -55,9 +57,9 @@ fn setup(mut commands: Commands) { fn customize_config(input: Res>, mut overlay: ResMut) { if input.just_pressed(KeyCode::Digit1) { // Changing resource will affect overlay - overlay.0.color = Color::srgb(1.0, 0.0, 0.0); + overlay.text_config.color = Color::srgb(1.0, 0.0, 0.0); } if input.just_pressed(KeyCode::Digit2) { - overlay.0.font_size -= 2.0; + overlay.text_config.font_size -= 2.0; } } From 8b160c8f981b160e133508c3cc1676a266ecf014 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sat, 9 Mar 2024 18:30:19 +0100 Subject: [PATCH 20/21] move doc comment to module --- crates/bevy_dev_tools/src/fps_overlay.rs | 2 ++ crates/bevy_dev_tools/src/lib.rs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 5e5d9546384dd..99333c3280968 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -1,3 +1,5 @@ +//! Module containing logic for FPS overlay. + use bevy_app::{Plugin, Startup, Update}; use bevy_asset::Handle; use bevy_color::Color; diff --git a/crates/bevy_dev_tools/src/lib.rs b/crates/bevy_dev_tools/src/lib.rs index 7a5f41dde1a57..9b38c99817968 100644 --- a/crates/bevy_dev_tools/src/lib.rs +++ b/crates/bevy_dev_tools/src/lib.rs @@ -5,7 +5,6 @@ use bevy_app::prelude::*; #[cfg(feature = "bevy_ci_testing")] pub mod ci_testing; -/// Module containing logic for FPS overlay. pub mod fps_overlay; /// Enables developer tools in an [`App`]. This plugin is added automatically with `bevy_dev_tools` From 2a4629ea17fba522dafdff4f4a209a5532803f8d Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sun, 10 Mar 2024 11:20:55 +0100 Subject: [PATCH 21/21] add todo comment --- crates/bevy_dev_tools/src/fps_overlay.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_dev_tools/src/fps_overlay.rs b/crates/bevy_dev_tools/src/fps_overlay.rs index 99333c3280968..51b8e7886dcf9 100644 --- a/crates/bevy_dev_tools/src/fps_overlay.rs +++ b/crates/bevy_dev_tools/src/fps_overlay.rs @@ -28,6 +28,7 @@ pub struct FpsOverlayPlugin { impl Plugin for FpsOverlayPlugin { fn build(&self, app: &mut bevy_app::App) { + // TODO: Use plugin dependencies, see https://github.com/bevyengine/bevy/issues/69 if !app.is_plugin_added::() { app.add_plugins(FrameTimeDiagnosticsPlugin); }