//! This example illustrates how to create UI text and update it in a system. //! //! It displays the current FPS in the top left corner, as well as text that changes color //! in the bottom right. For text within a scene, please see the text2d example. use bevy::{ color::palettes::css::GOLD, diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}, prelude::*, }; fn main() { App::new() .add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin)) .add_systems(Startup, setup) .add_systems(Update, (text_update_system, text_color_system)) .run(); } // A unit struct to help identify the FPS UI component, since there may be many Text components #[derive(Component)] struct FpsText; // A unit struct to help identify the color-changing Text component #[derive(Component)] struct ColorText; fn setup(mut commands: Commands, asset_server: Res) { // UI camera commands.spawn(Camera2dBundle::default()); // Text with one section commands.spawn(( // Create a TextBundle that has a Text with a single section. TextBundle::from_section( // Accepts a `String` or any type that converts into a `String`, such as `&str` "hello\nbevy!", TextStyle { // This font is loaded and will be used instead of the default font. font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 100.0, ..default() }, ) // Set the justification of the Text .with_text_justify(JustifyText::Center) // Set the style of the TextBundle itself. .with_style(Style { position_type: PositionType::Absolute, bottom: Val::Px(5.0), right: Val::Px(5.0), ..default() }), ColorText, )); // Text with multiple sections commands.spawn(( // Create a TextBundle that has a Text with a list of sections. TextBundle::from_sections([ TextSection::new( "FPS: ", TextStyle { // This font is loaded and will be used instead of the default font. font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 60.0, ..default() }, ), TextSection::from_style(if cfg!(feature = "default_font") { TextStyle { font_size: 60.0, color: GOLD.into(), // If no font is specified, the default font (a minimal subset of FiraMono) will be used. ..default() } } else { // "default_font" feature is unavailable, load a font to use instead. TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), font_size: 60.0, color: GOLD.into(), } }), ]), FpsText, )); #[cfg(feature = "default_font")] commands.spawn( // Here we are able to call the `From` method instead of creating a new `TextSection`. // This will use the default font (a minimal subset of FiraMono) and apply the default styling. TextBundle::from("From an &str into a TextBundle with the default font!").with_style( Style { position_type: PositionType::Absolute, bottom: Val::Px(5.0), left: Val::Px(15.0), ..default() }, ), ); #[cfg(not(feature = "default_font"))] commands.spawn( TextBundle::from_section( "Default font disabled", TextStyle { font: asset_server.load("fonts/FiraMono-Medium.ttf"), ..default() }, ) .with_style(Style { position_type: PositionType::Absolute, bottom: Val::Px(5.0), left: Val::Px(15.0), ..default() }), ); } fn text_color_system(time: Res