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"
|
||||
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"
|
||||
|
|
|
@ -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_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" }
|
||||
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 }
|
||||
|
|
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))]
|
||||
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
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