mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Fps overlay (#12382)
# Objective - Part of #12351 - Add fps overlay ## Solution - Create `FpsOverlayPlugin` - Allow for configuration through resource `FpsOverlayConfig` - Allow for configuration during runtime ### Preview on default settings ![20240308_22h23m25s_grim](https://github.com/bevyengine/bevy/assets/62356462/33d3d7a9-435e-4e0b-9814-d3274e779a69) --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
parent
27215b79b0
commit
2d29954034
6 changed files with 190 additions and 0 deletions
12
Cargo.toml
12
Cargo.toml
|
@ -2763,6 +2763,18 @@ description = "A scene showcasing light gizmos"
|
||||||
category = "Gizmos"
|
category = "Gizmos"
|
||||||
wasm = true
|
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]
|
[profile.wasm-release]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
|
|
|
@ -19,6 +19,12 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" }
|
||||||
bevy_render = { path = "../bevy_render", 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_time = { path = "../bevy_time", version = "0.14.0-dev" }
|
||||||
bevy_window = { path = "../bevy_window", 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" }
|
||||||
|
bevy_color = { path = "../bevy_color", version = "0.14.0-dev" }
|
||||||
|
bevy_input = { path = "../bevy_input", version = "0.14.0-dev" }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|
98
crates/bevy_dev_tools/src/fps_overlay.rs
Normal file
98
crates/bevy_dev_tools/src/fps_overlay.rs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
//! Module containing logic for FPS overlay.
|
||||||
|
|
||||||
|
use bevy_app::{Plugin, Startup, Update};
|
||||||
|
use bevy_asset::Handle;
|
||||||
|
use bevy_color::Color;
|
||||||
|
use bevy_diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin};
|
||||||
|
use bevy_ecs::{
|
||||||
|
component::Component,
|
||||||
|
query::With,
|
||||||
|
schedule::{common_conditions::resource_changed, IntoSystemConfigs},
|
||||||
|
system::{Commands, Query, Res, Resource},
|
||||||
|
};
|
||||||
|
use bevy_text::{Font, Text, TextSection, TextStyle};
|
||||||
|
use bevy_ui::node_bundles::TextBundle;
|
||||||
|
|
||||||
|
/// A plugin that adds an FPS overlay to the Bevy application.
|
||||||
|
///
|
||||||
|
/// 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`
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FpsOverlayPlugin {
|
||||||
|
/// Starting configuration of overlay, this can be later be changed through [`FpsOverlayConfig`] resource.
|
||||||
|
pub config: FpsOverlayConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
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::<FrameTimeDiagnosticsPlugin>() {
|
||||||
|
app.add_plugins(FrameTimeDiagnosticsPlugin);
|
||||||
|
}
|
||||||
|
app.insert_resource(self.config.clone())
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
|
customize_text.run_if(resource_changed::<FpsOverlayConfig>),
|
||||||
|
update_text,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration options for the FPS overlay.
|
||||||
|
#[derive(Resource, Clone)]
|
||||||
|
pub struct FpsOverlayConfig {
|
||||||
|
/// Configuration of text in the overlay.
|
||||||
|
pub text_config: TextStyle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FpsOverlayConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
FpsOverlayConfig {
|
||||||
|
text_config: TextStyle {
|
||||||
|
font: Handle::<Font>::default(),
|
||||||
|
font_size: 32.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct FpsText;
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands, overlay_config: Res<FpsOverlayConfig>) {
|
||||||
|
commands.spawn((
|
||||||
|
TextBundle::from_sections([
|
||||||
|
TextSection::new("FPS: ", overlay_config.text_config.clone()),
|
||||||
|
TextSection::from_style(overlay_config.text_config.clone()),
|
||||||
|
]),
|
||||||
|
FpsText,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_text(diagnostic: Res<DiagnosticsStore>, mut query: Query<&mut Text, With<FpsText>>) {
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn customize_text(
|
||||||
|
overlay_config: Res<FpsOverlayConfig>,
|
||||||
|
mut query: Query<&mut Text, With<FpsText>>,
|
||||||
|
) {
|
||||||
|
for mut text in &mut query {
|
||||||
|
for section in text.sections.iter_mut() {
|
||||||
|
section.style = overlay_config.text_config.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,10 @@
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
|
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
|
|
||||||
#[cfg(feature = "bevy_ci_testing")]
|
#[cfg(feature = "bevy_ci_testing")]
|
||||||
pub mod 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`
|
/// Enables developer tools in an [`App`]. This plugin is added automatically with `bevy_dev_tools`
|
||||||
/// feature.
|
/// feature.
|
||||||
|
|
|
@ -45,6 +45,7 @@ git checkout v0.4.0
|
||||||
- [Assets](#assets)
|
- [Assets](#assets)
|
||||||
- [Async Tasks](#async-tasks)
|
- [Async Tasks](#async-tasks)
|
||||||
- [Audio](#audio)
|
- [Audio](#audio)
|
||||||
|
- [Dev tools](#dev-tools)
|
||||||
- [Diagnostics](#diagnostics)
|
- [Diagnostics](#diagnostics)
|
||||||
- [ECS (Entity Component System)](#ecs-entity-component-system)
|
- [ECS (Entity Component System)](#ecs-entity-component-system)
|
||||||
- [Games](#games)
|
- [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 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
|
[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
|
## Diagnostics
|
||||||
|
|
||||||
Example | Description
|
Example | Description
|
||||||
|
|
65
examples/dev_tools/fps_overlay.rs
Normal file
65
examples/dev_tools/fps_overlay.rs
Normal file
|
@ -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 {
|
||||||
|
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)
|
||||||
|
.add_systems(Update, customize_config)
|
||||||
|
.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 customize_config(input: Res<ButtonInput<KeyCode>>, mut overlay: ResMut<FpsOverlayConfig>) {
|
||||||
|
if input.just_pressed(KeyCode::Digit1) {
|
||||||
|
// Changing resource will affect overlay
|
||||||
|
overlay.text_config.color = Color::srgb(1.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
if input.just_pressed(KeyCode::Digit2) {
|
||||||
|
overlay.text_config.font_size -= 2.0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue